Passed
Push — master ( 07b7c5...d13f2e )
by Alexey
05:08
created

RolesController::actionAddRoles()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
rs 9.0534
cc 4
eloc 14
nc 4
nop 0
1
<?php
2
3
namespace modules\rbac\controllers\backend;
4
5
use Yii;
6
use yii\data\ArrayDataProvider;
7
use yii\helpers\VarDumper;
8
use yii\web\Controller;
9
use yii\filters\AccessControl;
10
use yii\filters\VerbFilter;
11
use yii\web\BadRequestHttpException;
12
use modules\rbac\models\Role;
13
use modules\rbac\Module;
14
15
/**
16
 * Class RolesController
17
 * @package modules\rbac\controllers\backend
18
 */
19
class RolesController extends Controller
20
{
21
    /**
22
     * @inheritdoc
23
     */
24
    public function behaviors()
25
    {
26
        return [
27
            'access' => [
28
                'class' => AccessControl::className(),
29
                'rules' => [
30
                    [
31
                        'allow' => true,
32
                        'roles' => ['managerRbac'],
33
                    ],
34
                ],
35
            ],
36
            'verbs' => [
37
                'class' => VerbFilter::className(),
38
                'actions' => [
39
                    'delete' => ['POST']
40
                ],
41
            ],
42
        ];
43
    }
44
45
    /**
46
     * Lists all Role models.
47
     * @return mixed
48
     */
49
    public function actionIndex()
50
    {
51
        $auth = Yii::$app->authManager;
52
        $dataProvider = new ArrayDataProvider([
53
            'allModels' => $auth->getRoles(),
54
            'sort' => [
55
                'attributes' => ['name', 'description', 'ruleName'],
56
            ],
57
            'pagination' => [
58
                'pageSize' => 15,
59
            ],
60
        ]);
61
        return $this->render('index', [
62
            'dataProvider' => $dataProvider,
63
        ]);
64
    }
65
66
    /**
67
     * Displays a single Role model.
68
     * @param string $id
69
     * @return mixed
70
     */
71
    public function actionView($id)
72
    {
73
        $auth = Yii::$app->authManager;
74
        $role = $auth->getRole($id);
75
76
        $model = new Role(['name' => $role->name]);
77
        return $this->render('view', [
78
            'role' => $role,
79
            'model' => $model
80
        ]);
81
    }
82
83
    /**
84
     * Creates Role a new Role model.
85
     * If creation is successful, the browser will be redirected to the 'view' page.
86
     * @return mixed
87
     */
88
    public function actionCreate()
89
    {
90
        $model = new Role(['scenario' => Role::SCENARIO_CREATE]);
91
        $model->isNewRecord = true;
92
93
        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
94
            Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
95
            return \yii\widgets\ActiveForm::validate($model);
96
        }
97
98
        if ($model->load(Yii::$app->request->post())) {
99
            if ($model->validate()) {
100
                $auth = Yii::$app->authManager;
101
                $role = $auth->createRole($model->name);
102
                $role->description = $model->description;
103
                if ($auth->add($role)) {
104
                    return $this->redirect(['view', 'id' => $model->name]);
105
                }
106
            }
107
        }
108
        return $this->render('create', [
109
            'model' => $model,
110
        ]);
111
    }
112
113
    /**
114
     * Updates an existing Role model.
115
     * If update is successful, the browser will be redirected to the 'view' page.
116
     * @param string $id
117
     * @return mixed
118
     */
119
    public function actionUpdate($id)
120
    {
121
        $auth = Yii::$app->authManager;
122
        $role = $auth->getRole($id);
123
124
        $model = new Role([
125
            'scenario' => Role::SCENARIO_UPDATE,
126
            'name' => $role->name,
127
            'description' => $role->description,
128
        ]);
129
        if ($model->load(Yii::$app->request->post())) {
130
            $role->description = $model->description;
131
            if ($auth->update($id, $role)) {
132
                return $this->redirect(['view', 'id' => $id]);
133
            }
134
        }
135
        return $this->render('update', [
136
            'model' => $model,
137
        ]);
138
    }
139
140
    /**
141
     * Привязываем роль
142
     * @throws BadRequestHttpException
143
     */
144
    public function actionAddRoles()
145
    {
146
        $model = new Role([
147
            'scenario' => Role::SCENARIO_UPDATE,
148
        ]);
149
        if ($model->load(Yii::$app->request->post())) {
150
            $auth = Yii::$app->authManager;
151
            $role = $auth->getRole($model->name);
152
            foreach ($model->itemsRoles as $value) {
153
                $add = $auth->getRole($value);
154
                // Проверяем, не является добовляемая роль родителем?
155
                $result = $this->detectLoop($role, $add);
156
                if (!$result) {
157
                    $auth->addChild($role, $add);
158
                } else {
159
                    Yii::$app->session->setFlash('error', Module::t('module', 'The role of the "{:parent}" is the parent of the "{:role}"!', [':parent' => $add->name, ':role' => $role->name]));
160
                }
161
            }
162
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-roles']);
163
        }
164
        throw new BadRequestHttpException(Module::t('module', 'Not a valid request to the method!'));
165
    }
166
167
    /**
168
     * Отзываем роль
169
     * @return array|\yii\web\Response
170
     * @throws BadRequestHttpException
171
     */
172
    public function actionRemoveRoles()
173
    {
174
        $model = new Role([
175
            'scenario' => Role::SCENARIO_UPDATE,
176
        ]);
177
        if ($model->load(Yii::$app->request->post())) {
178
            $auth = Yii::$app->authManager;
179
            $role = $auth->getRole($model->name);
180
            foreach ($model->rolesByRole as $value) {
181
                $remove = $auth->getRole($value);
182
                $auth->removeChild($role, $remove);
183
            }
184
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-roles']);
185
        }
186
        throw new BadRequestHttpException(Module::t('module', 'Not a valid request to the method!'));
187
    }
188
189
    /**
190
     * Привязываем разрешение
191
     * @return array|\yii\web\Response
192
     * @throws BadRequestHttpException
193
     */
194
    public function actionAddPermissions()
195
    {
196
        $model = new Role([
197
            'scenario' => Role::SCENARIO_UPDATE,
198
        ]);
199
        if ($model->load(Yii::$app->request->post())) {
200
            $auth = Yii::$app->authManager;
201
            $role = $auth->getRole($model->name);
202
            foreach ($model->itemsPermissions as $value) {
203
                $add = $auth->getPermission($value);
204
                // Проверяем, не является добовляемое разрешение родителем?
205
                $result = $this->detectLoop($role, $add);
206
                if (!$result) {
207
                    $auth->addChild($role, $add);
208
                } else {
209
                    Yii::$app->session->setFlash('error', Module::t('module', 'The permission of the "{:parent}" is the parent of the "{:permission}"!', [':parent' => $add->name, ':permission' => $role->name]));
210
                }
211
            }
212
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-permissions']);
213
        }
214
        throw new BadRequestHttpException(Module::t('module', 'Not a valid request to the method!'));
215
    }
216
217
    /**
218
     * Отзываем разрешение
219
     * @return array|\yii\web\Response
220
     * @throws BadRequestHttpException
221
     */
222
    public function actionRemovePermissions()
223
    {
224
        $model = new Role([
225
            'scenario' => Role::SCENARIO_UPDATE,
226
        ]);
227
        if ($model->load(Yii::$app->request->post())) {
228
            $auth = Yii::$app->authManager;
229
            $role = $auth->getRole($model->name);
230
            foreach ($model->permissionsByRole as $value) {
231
                $remove = $auth->getPermission($value);
232
                $auth->removeChild($role, $remove);
233
            }
234
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-permissions']);
235
        }
236
        throw new BadRequestHttpException(Module::t('module', 'Not a valid request to the method!'));
237
    }
238
239
    /**
240
     * Deletes an existing Role model.
241
     * If deletion is successful, the browser will be redirected to the 'index' page.
242
     * @param string $id
243
     * @return mixed
244
     */
245
    public function actionDelete($id)
246
    {
247
        $auth = Yii::$app->authManager;
248
        $role = $auth->getRole($id);
249
        if ($auth->remove($role)) {
250
            Yii::$app->session->setFlash('success', Module::t('module', 'The role "{:name}" have been successfully deleted.', [':name' => $role->name]));
251
        } else {
252
            Yii::$app->session->setFlash('error', Module::t('module', 'Error!'));
253
        }
254
        return $this->redirect(['index']);
255
    }
256
257
    /**
258
     * @param $parent
259
     * @param $child
260
     * @return bool
261
     */
262
    protected function detectLoop($parent, $child)
263
    {
264
        $auth = Yii::$app->authManager;
265
        if ($child->name === $parent->name) {
266
            return true;
267
        }
268
        foreach ($auth->getChildren($child->name) as $grandchild) {
269
            if ($this->detectLoop($parent, $grandchild)) {
270
                return true;
271
            }
272
        }
273
        return false;
274
    }
275
}
276