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