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

PermissionsController::actionAddPermissions()   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\web\Controller;
8
use yii\filters\VerbFilter;
9
use yii\filters\AccessControl;
10
use yii\web\BadRequestHttpException;
11
use modules\rbac\models\Permission;
12
use modules\rbac\Module;
13
14
/**
15
 * Class PermissionsController
16
 * @package modules\rbac\controllers\backend
17
 */
18
class PermissionsController extends Controller
19
{
20
    /**
21
     * @inheritdoc
22
     */
23
    public function behaviors()
24
    {
25
        return [
26
            'access' => [
27
                'class' => AccessControl::className(),
28
                'rules' => [
29
                    [
30
                        'allow' => true,
31
                        'roles' => ['managerRbac'],
32
                    ],
33
                ],
34
            ],
35
            'verbs' => [
36
                'class' => VerbFilter::className(),
37
                'actions' => [
38
                    'delete' => ['POST']
39
                ],
40
            ],
41
        ];
42
    }
43
44
    /**
45
     * Lists all Permission models.
46
     * @return mixed
47
     */
48
    public function actionIndex()
49
    {
50
        $auth = Yii::$app->authManager;
51
        $dataProvider = new ArrayDataProvider([
52
            'allModels' => $auth->getPermissions(),
53
            'sort' => [
54
                'attributes' => ['name', 'description', 'ruleName'],
55
            ],
56
            'pagination' => [
57
                'pageSize' => 15,
58
            ],
59
        ]);
60
        return $this->render('index', [
61
            'dataProvider' => $dataProvider,
62
        ]);
63
    }
64
65
    /**
66
     * Displays a single Permission model.
67
     * @param string $id
68
     * @return mixed
69
     */
70
    public function actionView($id)
71
    {
72
        $auth = Yii::$app->authManager;
73
        $permission = $auth->getPermission($id);
74
75
        $model = new Permission(['name' => $permission->name]);
76
        return $this->render('view', [
77
            'permission' => $permission,
78
            'model' => $model,
79
        ]);
80
    }
81
82
    /**
83
     * Creates Permission a new Permission model.
84
     * If creation is successful, the browser will be redirected to the 'view' page.
85
     * @return mixed
86
     */
87
    public function actionCreate()
88
    {
89
        $model = new Permission(['scenario' => Permission::SCENARIO_CREATE]);
90
        $model->isNewRecord = true;
91
92
        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
93
            Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
94
            return \yii\widgets\ActiveForm::validate($model);
95
        }
96
97
        if ($model->load(Yii::$app->request->post())) {
98
            if ($model->validate()) {
99
                $auth = Yii::$app->authManager;
100
                $perm = $auth->createPermission($model->name);
101
                $perm->description = $model->description;
102
                if ($auth->add($perm)) {
103
                    return $this->redirect(['view', 'id' => $model->name]);
104
                }
105
            }
106
        }
107
        return $this->render('create', [
108
            'model' => $model,
109
        ]);
110
    }
111
112
    /**
113
     * Updates an existing Permission model.
114
     * If update is successful, the browser will be redirected to the 'view' page.
115
     * @param string $id
116
     * @return mixed
117
     */
118
    public function actionUpdate($id)
119
    {
120
        $auth = Yii::$app->authManager;
121
        $perm = $auth->getPermission($id);
122
123
        $model = new Permission([
124
            'scenario' => Permission::SCENARIO_UPDATE,
125
            'name' => $perm->name,
126
            'description' => $perm->description,
127
        ]);
128
        if ($model->load(Yii::$app->request->post())) {
129
            $perm->description = $model->description;
130
            if ($auth->update($id, $perm)) {
131
                return $this->redirect(['view', 'id' => $id]);
132
            }
133
        }
134
        return $this->render('update', [
135
            'model' => $model,
136
        ]);
137
    }
138
139
    /**
140
     * Привязываем разрешение
141
     * @return array|\yii\web\Response
142
     * @throws BadRequestHttpException
143
     */
144
    public function actionAddPermissions()
145
    {
146
        $model = new Permission([
147
            'scenario' => Permission::SCENARIO_UPDATE,
148
        ]);
149
        if ($model->load(Yii::$app->request->post())) {
150
            $auth = Yii::$app->authManager;
151
            $permission = $auth->getPermission($model->name);
152
            foreach ($model->permissionItems as $perm) {
153
                $add = $auth->getPermission($perm);
154
                // Проверяем, не является добовляемое разрешение родителем?
155
                $result = $this->detectLoop($permission, $add);
156
                if (!$result) {
157
                    $auth->addChild($permission, $add);
158
                } else {
159
                    Yii::$app->session->setFlash('error', Module::t('module', 'The permission of the "{:parent}" is the parent of the "{:permission}"!', [':parent' => $add->name, ':permission' => $permission->name]));
160
                }
161
            }
162
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-permissions']);
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 actionRemovePermissions()
173
    {
174
        $model = new Permission([
175
            'scenario' => Permission::SCENARIO_UPDATE,
176
        ]);
177
        if ($model->load(Yii::$app->request->post())) {
178
            $auth = Yii::$app->authManager;
179
            $permission = $auth->getPermission($model->name);
180
            foreach ($model->permissions as $perm) {
181
                $remove = $auth->getPermission($perm);
182
                $auth->removeChild($permission, $remove);
183
            }
184
            return $this->redirect(['update', 'id' => $model->name, '#' => 'assign-container-permissions']);
185
        }
186
        throw new BadRequestHttpException(Module::t('module', 'Not a valid request to the method!'));
187
    }
188
189
    /**
190
     * Deletes an existing Permission model.
191
     * If deletion is successful, the browser will be redirected to the 'index' page.
192
     * @param string $id
193
     * @return mixed
194
     */
195
    public function actionDelete($id)
196
    {
197
        $auth = Yii::$app->authManager;
198
        $perm = $auth->getPermission($id);
199
        if ($auth->remove($perm)) {
200
            Yii::$app->session->setFlash('success', Module::t('module', 'The permission "{:name}" have been successfully deleted.', [':name' => $perm->name]));
201
        } else {
202
            Yii::$app->session->setFlash('error', Module::t('module', 'Error!'));
203
        }
204
        return $this->redirect(['index']);
205
    }
206
207
    /**
208
     * @param $parent
209
     * @param $child
210
     * @return bool
211
     */
212
    protected function detectLoop($parent, $child)
213
    {
214
        $auth = Yii::$app->authManager;
215
        if ($child->name === $parent->name) {
216
            return true;
217
        }
218
        foreach ($auth->getChildren($child->name) as $grandchild) {
219
            if ($this->detectLoop($parent, $grandchild)) {
220
                return true;
221
            }
222
        }
223
        return false;
224
    }
225
}
226