Permitions   F
last analyzed

Complexity

Total Complexity 150

Size/Duplication

Total Lines 1044
Duplicated Lines 4.5 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 47
loc 1044
rs 1.424
c 0
b 0
f 0
wmc 150
lcom 1
cbo 2

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A checkPermitions() 0 4 1
A checkModuleInstall() 0 16 5
A getInstalledMudules() 0 11 3
B checkAllPermitions() 0 54 10
F checkUrl() 0 70 18
B processRbacPrivileges() 0 38 11
B scanControllers() 0 50 10
B checkSuperAdmin() 0 24 6
A createSuperAdmin() 0 17 5
B groupCreate() 21 52 7
B groupEdit() 5 49 7
A groupList() 0 15 1
A groupDelete() 0 12 3
C roleCreate() 6 63 10
A translateRole() 0 38 4
C roleEdit() 0 115 12
A roleList() 0 9 1
A getRoles() 0 6 1
A roleDelete() 0 17 3
A privilegeCreate() 0 44 4
B privilegeEdit() 15 41 5
A privilegeList() 0 26 2
A privilegeDelete() 0 11 2
A checkControlPanelAccess() 0 17 3
A deletePermition() 0 10 2
B makeRolesArray() 0 39 9
A filterShopPrivileges() 0 22 3
A error404() 0 5 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Permitions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Permitions, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
if (!defined('BASEPATH')) {
4
    exit('No direct script access allowed');
5
}
6
7
class Permitions extends BaseAdminController
8
{
9
10
    private static $shop_controllers_path;  //define shop admin controllers path
11
12
    private static $base_controllers_path;       //define base admin controllers path
13
14
    private static $modules_controllers_path = '/application/modules/';          //define modules path
15
16
    private static $rbac_roles_table = 'shop_rbac_roles';                       //define rbac roles table name
17
18
    private static $rbac_privileges_table = 'shop_rbac_privileges';             //define privileges table name
19
20
    private static $rbac_group_table = 'shop_rbac_group';                       //define group table
21
22
    private static $rbac_roles_privileges_table = 'shop_rbac_roles_privileges'; //define roles privileges table
23
24
    private static $controller_types = [
25
                                        'shop',
26
                                        'base',
27
                                        'module',
28
                                       ];         //define controllers types
29
30
    private static $installed_modules = [];         //define installed modules
31
32
    public function __construct() {
33
        $ci = &get_instance();
34
        $ci->load->library('DX_Auth');
35
        self::$shop_controllers_path = getModulePath('shop') . 'admin/';
36
        self::$base_controllers_path = getModulePath('admin');
37
    }
38
39
    /**
40
     * runs in BaseAdminController and ShopAdminController __construct()
41
     */
42
    public static function checkPermitions() {
43
        self::checkUrl();
44
        self::checkModuleInstall();
45
    }
46
47
    /**
48
     * Check module install by requested url
49
     */
50
    private static function checkModuleInstall() {
51
        $for_check = CI::$APP->uri->segment(2);
52
53
        if ($for_check == 'components') {
54
            if (in_array(CI::$APP->uri->segment(3), ['init_window', 'run', 'cp'])) {
55
                $module = CI::$APP->uri->segment(4);
56
            }
57
        }
58
59
        if ($module) {
60
            self::getInstalledMudules();
61
            if (!self::$installed_modules[$module]) {
62
                redirect('admin/rbac/not_installed_module_error');
63
            }
64
        }
65
    }
66
67
    /**
68
     * Get installed modules array
69
     * @return array
70
     */
71
    private static function getInstalledMudules() {
72
        if (!self::$installed_modules) {
73
            $modules = CI::$APP->db->select('id, name')->get('components')->result_array();
74
            foreach ($modules as $key => $module) {
75
                $modules[$module['name']] = $module;
76
                unset($modules[$key]);
77
            }
78
            self::$installed_modules = $modules;
79
        }
80
        return self::$installed_modules;
81
    }
82
83
    /**
84
     *
85
     * @param string $adminClassName
86
     * @param string $adminMethod
87
     * @return boolean|null
88
     */
89
    private static function checkAllPermitions($adminClassName, $adminMethod) {
90
        $ci = &get_instance();
91
92
        //check if user is loged in
93
        if ($ci->dx_auth->is_logged_in()) {
94
            //creating string for search in rbac privileges table
95
            $privilege = $adminClassName . '::' . $adminMethod;
96
97
            //searching privilege
98
            $privilege = $ci->db->where('name', $privilege)->get(self::$rbac_privileges_table)->row();
99
100
            //searching user by id to get his role id
101
            $userProfile = $ci->db->where('id', $ci->dx_auth->get_user_id())->get('users')->row();
102
103
            //if user exists!
104
            if (!empty($userProfile)) {
105
                //get user role
106
                $userRole = $ci->db->where('id', $userProfile->role_id)->get(self::$rbac_roles_table)->row();
107
            }
108
109
            //if privilege found
110
            if (!empty($privilege)) {
111
                //check if role exists
112
                if (!empty($userRole)) {
113
                    //check if user has needed privilege
114
                    $userPrivilege = $ci->db->where(['role_id' => (int) $userRole->id, 'privilege_id' => (int) $privilege->id])->get(self::$rbac_roles_privileges_table)->result();
115
                    if (!empty($userPrivilege)) {
116
                        //yes, current user has needed privilege
117
                        return TRUE;
118
                    } else {
119
                        //no, permission denied
120
                        redirect('admin/rbac/permition_denied');
121
                    }
122
                }
123
            } else {
124
                //if privilege not found in base check if user is admin
125
                if ($userRole->name != 'Administrator' AND $adminMethod != 'permition_denied') {
126
                    redirect('admin/rbac/permition_denied');
127
                }
128
            }
129
        } else {
130
            //user always has access to admin/login page
131
            if ($adminClassName != 'Login') {
132
                $loginUrl = '/admin/login';
133
                if ($ci->input->is_ajax_request()) {
134
                    ajax_redirect($loginUrl);
135
                    exit;
136
                } else {
137
                    $_SESSION['redirect_after_login'] = $ci->uri->uri_string;
138
                    redirect($loginUrl);
139
                }
140
            }
141
        }
142
    }
143
144
    /**
145
     * parsing url to get needed parameters
146
     * @param string|bool $checkLink
147
     * @param string $link
148
     * @return array with class name and class method
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
149
     */
150
    private static function checkUrl($checkLink = FALSE, $link = '') {
151
        $ci = &get_instance();
152
153
        if ($checkLink AND $link != '') {
154
            $uri_array = explode('/', $link);
155
            $for_check = $uri_array[1];
156
        } else {
157
            $for_check = $ci->uri->segment(2);
158
        }
159
160
        if ($for_check == 'components') {
161
            if (in_array($ci->uri->segment(3), ['init_window', 'run', 'cp']) OR in_array($uri_array[2], ['init_window', 'run', 'cp'])) {
162
                $classNamePrep = 'Admin';
163
                $controller_segment = 4;
164
                $controller_method = 5;
165
            } else {
166
                $controller_segment = 2;
167
                $controller_method = 3;
168
                $classNamePrep = 'Base';
169
            }
170
            if ($ci->uri->segment(4) == 'shop' OR $uri_array[3] == 'shop') {
171
                $classNamePrep = 'ShopAdmin';
172
                $controller_segment = 5;
173
                $controller_method = 6;
174
            }
175
        } else {
176
            $controller_segment = 2;
177
            $controller_method = 3;
178
            $classNamePrep = 'Base';
179
        }
180
181
        if ($checkLink AND $link != '') {
182
            $adminController = $uri_array[$controller_segment - 1];
183
        } else {
184
            $adminController = $ci->uri->segment($controller_segment);
185
        }
186
187
        switch ($classNamePrep) {
188
            case 'ShopAdmin':
189
                $adminClassName = 'ShopAdmin' . ucfirst($adminController);
190
                $adminClassFile = self::$shop_controllers_path . $adminController . '.php';
0 ignored issues
show
Unused Code introduced by
$adminClassFile is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
191
                break;
192
            case 'Admin':
193
                $adminClassName = $adminController;
194
                $adminClassFile = self::$modules_controllers_path . $adminController . '/admin.php';
0 ignored issues
show
Unused Code introduced by
$adminClassFile is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
195
                break;
196
            case 'Base':
197
                $adminClassName = ucfirst($adminController);
198
                $adminClassFile = self::$base_controllers_path . $adminController . '.php';
0 ignored issues
show
Unused Code introduced by
$adminClassFile is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
199
                break;
200
        }
201
        if ($checkLink AND $link != '') {
202
            $adminMethod = $uri_array[$controller_method - 1];
203
        } else {
204
            $adminMethod = $ci->uri->segment($controller_method);
205
        }
206
207
        if (!$adminMethod) {
208
            $adminMethod = 'index';
209
        }
210
211
        if ($checkLink AND $link != '') {
212
            return [
213
                    'adminClassName' => $adminClassName,
214
                    'adminMethod'    => $adminMethod,
215
                   ];
216
        } else {
217
            self::checkAllPermitions($adminClassName, $adminMethod);
218
        }
219
    }
220
221
    /**
222
     * scans all admin controllers
223
     */
224
    private static function processRbacPrivileges() {
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
225
        $ci = &get_instance();
226
        $controllerFolders = self::$controller_types;
227
        foreach ($controllerFolders as $folder) {
228
            if ($folder == 'base') {
229
                $adminControllersDir = self::$base_controllers_path;
230
            }
231
            if ($folder == 'shop') {
232
                $adminControllersDir = self::$shop_controllers_path;
233
            }
234
            if ($folder == 'module') {
235
                $adminControllersDir = self::$modules_controllers_path;
236
                $ci->load->helper('directory');
237
                $controllers = directory_map($adminControllersDir, true);
238
                foreach ($controllers as $c) {
239
                    if (file_exists($adminControllersDir . $c . '/admin.php') AND !in_array($c, ['shop', 'admin'])) {
240
                        $result[] = $adminControllersDir . $c . '/admin.php';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
241
                    }
242
                }
243
                $controllers = $result;
244
            }
245
            $fileExtension = EXT;
246
247
            if ($handle = opendir($adminControllersDir)) {
248
                //list of the admin controllers
249
                if (!$controllers) {
250
                    $controllers = glob($adminControllersDir . "*$fileExtension");
251
                }
252
                foreach ($controllers as $controller) {
253
254
                    self::scanControllers($controller, $folder);
255
                }
256
                $controllers = false;
257
                closedir($handle);
258
            }
259
        }
260
        showMessage('Успех');
261
    }
262
263
    /**
264
     * scans needed controller for public methods and write them into privileges table
265
     * @param string $controller
266
     * @param string $folder
267
     */
268
    private static function scanControllers($controller, $folder) {
269
        $locale = MY_Controller::getCurrentLocale();
270
        $ci = &get_instance();
271
        $fileExtension = EXT;
272
        if ($folder == 'module') {
273
            $arr = explode('/', $controller);
274
            $text = file_get_contents($controller);
275
            $text = str_replace('class Admin', 'class ' . $arr[2], $text);
276
            write_file(str_replace('admin.php', $arr[2] . 'temp' . $fileExtension, $controller), $text);
277
            $controller = str_replace('admin.php', $arr[2] . 'temp' . $fileExtension, $controller);
278
        }
279
280
        include_once $controller;
281
        $controllerName = str_replace('temp', '', basename($controller, $fileExtension));
282
        switch ($folder) {
283
            case 'base':
284
                $controllerClassName = ucfirst($controllerName);
285
                break;
286
            case 'module':
287
                $controllerClassName = $arr[2];
288
                break;
289
            case 'shop':
290
                $controllerClassName = 'ShopAdmin' . ucfirst($controllerName);
291
                break;
292
        }
293
294
        $class = new ReflectionClass($controllerClassName);
295
296
        $controllerMethods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
297
298
        foreach ($controllerMethods as $controllerMethod) {
299
            if ($controllerMethod->class == $controllerClassName) {
300
                $privilegeName = $controllerMethod->class . '::' . $controllerMethod->name;
301
                $dbPrivilege = $ci->db->where('name', $privilegeName)->get(self::$rbac_privileges_table)->row();
302
                $group = $ci->db->where('name', ucfirst($controllerClassName))->get(self::$rbac_group_table)->row();
303
                if (empty($group)) {
304
                    $ci->db->insert(self::$rbac_group_table, ['name' => ucfirst($controllerClassName), 'type' => $folder]);
305
                    $ci->db->insert(self::$rbac_group_table . '_i18n', ['id' => $ci->db->insert_id(), 'description' => '', 'locale' => $locale]);
306
                    $group = $ci->db->where('name', ucfirst($controllerClassName))->get(self::$rbac_group_table)->row();
307
                }
308
                if (empty($dbPrivilege)) {
309
                    $ci->db->insert(self::$rbac_privileges_table, ['name' => $privilegeName, 'group_id' => $group->id]);
310
                    $ci->db->insert(self::$rbac_privileges_table . '_i18n', ['id' => $ci->db->insert_id(), 'title' => '', 'description' => '', 'locale' => $locale]);
311
                }
312
            }
313
        }
314
        if ($folder == 'module') {
315
            unlink($controller);
316
        }
317
    }
318
319
    /**
320
     * check if user with id = 1 exists and has all privileges
321
     * @return null|boolean
322
     */
323
    private static function checkSuperAdmin() {
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
324
        $ci = &get_instance();
325
        $superAdmin = $ci->db->where('id', 1)->get('users')->row();
326
        if (empty($superAdmin)) {
327
            die('Супер администратор не найден');
328
        } else {
329
            $role_id = $superAdmin->role_id;
330
            $privileges = $ci->db->get(self::$rbac_privileges_table)->result();
331
            if (!empty($privileges)) {
332
                $countAllPermitions = count($privileges);
333
                $countUserPermitions = 0;
334
                foreach ($privileges as $privilege) {
335
                    if ($ci->db->where(['privilege_id' => $privilege->id, 'role_id' => $role_id])->get(self::$rbac_roles_privileges_table)->num_rows() > 0) {
336
                        $countUserPermitions++;
337
                    }
338
                }
339
                if ($countAllPermitions == $countUserPermitions) {
340
                    return true;
341
                } else {
342
                    die('Суперадмин не найден');
343
                }
344
            }
345
        }
346
    }
347
348
    /**
349
     * add all privileges to superadmin role
350
     */
351
    private static function createSuperAdmin() {
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
352
        $ci = &get_instance();
353
        $superAdmin = $ci->db->where('id', 1)->get('users')->row();
354
        if (empty($superAdmin)) {
355
            die('Супер администратор не найден');
356
        } else {
357
            $role_id = $superAdmin->role_id;
358
            $privileges = $ci->db->get(self::$rbac_privileges_table)->result();
359
            if (!empty($privileges)) {
360
                foreach ($privileges as $privilege) {
361
                    if ($ci->db->where(['privilege_id' => $privilege->id, 'role_id' => $role_id])->get(self::$rbac_roles_privileges_table)->num_rows() == 0) {
362
                        $ci->db->insert(self::$rbac_roles_privileges_table, ['role_id' => $role_id, 'privilege_id' => $privilege->id]);
363
                    }
364
                }
365
            }
366
        }
367
    }
368
369
    /*     * *************  RBAC privileges groups  ************** */
370
371
    /**
372
     * create a RBAC privileges group
373
     *
374
     * @access public
375
     * @return    void
376
     */
377
    public function groupCreate() {
378
379
        $this->form_validation->set_rules('Name', 'Name', 'required');
380
381
        if ($this->input->post()) {
382
            if ($this->form_validation->run($this) == FALSE) {
383
                showMessage(validation_errors(), '', 'r');
384
            } else {
385
386
                $sql = 'INSERT INTO shop_rbac_group (type, name) VALUES(' . $this->db->escape($this->input->post('type')) . ',' . $this->db->escape($this->input->post('Name')) . ')';
387
                $this->db->query($sql);
388
389
                $idNewGroup = $this->db->insert_id();
390
391
                $sql = 'INSERT INTO  shop_rbac_group_i18n (id, description, locale) VALUES(' . $idNewGroup . ', ' . $this->db->escape($this->input->post('Description')) . ", '" . MY_Controller::getCurrentLocale() . "' ) ";
392
393
                $this->db->query($sql);
394
395 View Code Duplication
                if ($this->input->post('Privileges')) {
396
                    $idPrivilege = implode(',', $this->input->post('Privileges'));
397
                    $sql = 'UPDATE shop_rbac_privileges SET group_id = ' . $idNewGroup . ' WHERE id IN(' . $idPrivilege . ')';
398
                    $this->db->query($sql);
399
                }
400
401
                showMessage('Группа создана');
402
                if ($this->input->post('action') == 'tomain') {
403
                    pjax('/admin/rbac/groupEdit/' . $idNewGroup);
404
                }
405
                if ($this->input->post('action') == 'tocreate') {
406
                    pjax('/admin/rbac/groupCreate');
407
                }
408
                if ($this->input->post('action') == 'toedit') {
409
                    pjax('/admin/rbac/groupEdit/' . $idNewGroup);
410
                }
411
            }
412 View Code Duplication
        } else {
413
414
            $sqlModel = 'SELECT SRP.id, SRP.name, SRP.group_id, SRPI.title, SRPI.description
415
            FROM shop_rbac_privileges SRP
416
            INNER JOIN shop_rbac_privileges_i18n SRPI ON SRPI.id = SRP.id WHERE SRPI.locale = "' . MY_Controller::getCurrentLocale() . '"  ORDER BY SRP.name ASC';
417
            $model = $this->db->query($sqlModel);
418
419
            $this->template->add_array(
420
                [
421
                 'model'      => $model,
422
                 'privileges' => $model->result(),
423
                ]
424
            );
425
426
            $this->template->show('groupCreate', FALSE);
427
        }
428
    }
429
430
    public function groupEdit($groupId) {
431
432
        $sqlModel = 'SELECT SRG.id, SRG.name, SRGI.description
433
            FROM shop_rbac_group SRG
434
            INNER JOIN shop_rbac_group_i18n SRGI ON SRGI.id = SRG.id WHERE SRG.id = "' . $groupId . '" AND SRGI.locale = "' . MY_Controller::getCurrentLocale() . '"  ORDER BY SRG.name ASC';
435
        $model = $this->db->query($sqlModel);
436
437
        if ($model === null) {
438
            $this->error404('Группа не найдена');
439
        }
440
441
        if ($this->input->post()) {
442
443
            $sql = 'UPDATE shop_rbac_group SET name = ' . $this->db->escape($this->input->post('Name')) .
444
                ' WHERE id = ' . $groupId;
445
            $this->db->query($sql);
446
447
            $sql = 'UPDATE shop_rbac_group_i18n SET description = ' . $this->db->escape($this->input->post('Description')) . ' WHERE id = ' . $groupId . " AND locale = '" . MY_Controller::getCurrentLocale() . "'";
448
            $this->db->query($sql);
449
450 View Code Duplication
            if ($this->input->post('Privileges')) {
451
                $idPrivilege = implode(',', $this->input->post('Privileges'));
452
                $sql = 'UPDATE shop_rbac_privileges SET group_id = ' . $groupId . ' WHERE id IN(' . $idPrivilege . ')';
453
                $this->db->query($sql);
454
            }
455
            showMessage('Изменения сохранены');
456
            if ($this->input->post('action') == 'tomain') {
457
                pjax('/admin/rbac/groupEdit/' . $groupId);
458
            }
459
            if ($this->input->post('action') == 'tocreate') {
460
                pjax('/admin/rbac/groupCreate');
461
            }
462
            if ($this->input->post('action') == 'toedit') {
463
                pjax('/admin/rbac/groupEdit/' . $groupId);
464
            }
465
        } else {
466
467
            $sqlPrivilege = $this->db->select(['id', 'name', 'group_id'])->get('shop_rbac_privileges')->result();
468
469
            $this->template->add_array(
470
                [
471
                 'model'      => $model->row(),
472
                 'privileges' => $sqlPrivilege,
473
                ]
474
            );
475
476
            $this->template->show('groupEdit', FALSE);
477
        }
478
    }
479
480
    public function groupList() {
481
482
        $sql = 'SELECT SRG.id, SRG.name, SRGI.description
483
            FROM shop_rbac_group SRG
484
            INNER JOIN shop_rbac_group_i18n SRGI ON SRGI.id = SRG.id WHERE SRGI.locale = "' . MY_Controller::getCurrentLocale() . '" ORDER BY name ASC';
485
        $query = $this->db->query($sql);
486
487
        $this->template->add_array(
488
            [
489
             'model' => $query->result(),
490
            ]
491
        );
492
493
        $this->template->show('groupList', FALSE);
494
    }
495
496
    /**
497
     * delete a RBAC privileges group
498
     *
499
     * @access public
500
     * @return    void
501
     */
502
    public function groupDelete() {
503
        $groupId = $this->input->post('ids');
504
505
        if ($groupId != null) {
506
            foreach ($groupId as $id) {
507
                $this->db->delete('shop_rbac_group', ['id' => $id]);
508
                $this->db->delete('shop_rbac_group_i18n', ['id' => $id]);
509
            }
510
            showMessage('Успех', 'Группа(ы) успешно удалены');
511
            pjax('/admin/rbac/groupList');
512
        }
513
    }
514
515
    /*     * *************  RBAC roles  ************** */
516
517
    /**
518
     * create a RBAC role
519
     *
520
     * @access public
521
     * @return     void
522
     */
523
    public function roleCreate() {
524
        if ($this->input->post()) {
525
            $this->form_validation->set_rules('Name', lang('Title'), 'required');
526
            $this->form_validation->set_rules('Importance', lang('Важность'), 'numeric');
527
            if ($this->form_validation->run($this) == FALSE) {
528
                showMessage(validation_errors(), '', 'r');
529
            } else {
530
                if ($this->db->where('name', $this->input->post('Name'))->get(self::$rbac_roles_table)->num_rows() == 0) {
531
                    $sql = 'INSERT INTO shop_rbac_roles(name, importance) VALUES(' . $this->db->escape($this->input->post('Name')) . ', ' . $this->db->escape($this->input->post('Importance')) .
532
                        ')';
533
                    $this->db->query($sql);
534
                    $idCreate = $this->db->insert_id();
535
                    $languages = $this->db->get('languages')->result_array();
536
                    foreach ($languages as $lang) {
537
                        $sql = 'INSERT INTO shop_rbac_roles_i18n(id, alt_name, locale, description) VALUES(' . $idCreate . ', ' . $this->db->escape($this->input->post('Name')) .
538
                            ",  '" . $lang['identif'] . "',  "
539
                            . $this->db->escape($this->input->post('Description')) . ')';
540
                        $this->db->query($sql);
541
                    }
542
543 View Code Duplication
                    if ($this->input->post('Privileges')) {
544
                        foreach ($this->input->post('Privileges') as $idPrivilege) {
545
                            $sqlPrivilege = 'INSERT INTO shop_rbac_roles_privileges (role_id, privilege_id) VALUES(' . $idCreate . ', ' . $this->db->escape($idPrivilege) . ')';
546
                            $this->db->query($sqlPrivilege);
547
                        }
548
                    }
549
550
                    $last_role_id = $this->db->order_by('id', 'desc')->get('shop_rbac_roles')->row()->id;
551
                    $this->lib_admin->log(lang('The role is created') . '. Id: ' . $last_role_id);
552
                    showMessage(lang('Changes have been saved'));
553
                    if ($this->input->post('action') == 'new') {
554
                        pjax('/admin/rbac/roleEdit/' . $idCreate);
555
                    } else {
556
                        pjax('/admin/rbac/roleList');
557
                    }
558
                } else {
559
                    showMessage('Такое имя для роли уже занято');
560
                }
561
            }
562
        } else {
563
            //preparing array of controller types
564
            $types = $this->db->query('SELECT DISTINCT `type` FROM ' . self::$rbac_group_table)->result_array();
565
            foreach ($types as $item) {
566
                $controller_types[] = $item['type'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$controller_types was never initialized. Although not strictly required by PHP, it is generally a good practice to add $controller_types = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
567
            }
568
569
            //preparing groups
570
571
            $locale = MY_Controller::defaultLocale();
572
            $res = $this->db->select('id')->get_where(self::$rbac_group_table . '_i18n', ['locale' => $locale])->result_array();
573
            if (count($res) < 1) {
574
                $locale = 'en';
575
            }
576
577
            $result = self::makeRolesArray($controller_types, $locale);
578
579
            $this->template->add_array(
580
                ['types' => $result]
581
            );
582
583
            $this->template->show('roleCreate', FALSE);
584
        }
585
    }
586
587
    public function translateRole($id, $lang) {
588
589
        $sqlModel = 'SELECT id, alt_name, locale, description
590
            FROM  shop_rbac_roles_i18n
591
            WHERE id = "' . $id . '" AND locale = "' . $lang . '"';
592
593
        $queryModel = $this->db->query($sqlModel)->row();
594
595
        if ($this->input->post()) {
596
            if (empty($queryModel)) {
597
598
                $sql = 'INSERT INTO shop_rbac_roles_i18n(id, alt_name, locale, description) VALUES(' . $id . ', ' . $this->db->escape($this->input->post('alt_name')) .
599
                    ",  '" . $lang . "',  "
600
                    . $this->db->escape($this->input->post('Description')) . ')';
601
                $this->db->query($sql);
602
            } else {
603
                $sqlI = 'UPDATE shop_rbac_roles_i18n SET alt_name = ' . $this->db->escape($this->input->post('alt_name')) . ", locale = '" . $lang . "', description = " . $this->db->escape($this->input->post('Description')) . " WHERE id = '" . $id . "' AND locale = '" . $lang . "'";
604
                $this->db->query($sqlI);
605
            }
606
607
            showMessage(lang('Changes have been saved'));
608
            if ($this->input->post('action') == 'edit') {
609
                pjax('/admin/rbac/translateRole/' . $id . '/' . $lang);
610
            } else {
611
                pjax('/admin/rbac/roleList');
612
            }
613
        } else {
614
615
            $this->template->add_array(
616
                [
617
                 'model'    => $queryModel,
618
                 'idRole'   => $id,
619
                 'lang_sel' => $lang,
620
                ]
621
            );
622
            $this->template->show('translateRole', FALSE);
623
        }
624
    }
625
626
    /**
627
     * edit a RBAC role
628
     *
629
     * @access    public
630
     * @param    integer $roleId
631
     * @return    void
632
     */
633
    public function roleEdit($roleId) {
634
635
        $locale = MY_Controller::getCurrentLocale();
636
637
        $queryModel = $this->db->select('shop_rbac_roles.id, shop_rbac_roles.name , shop_rbac_roles.importance, shop_rbac_roles_i18n.alt_name, shop_rbac_roles_i18n.description ')
638
            ->from('shop_rbac_roles')
639
            ->join('shop_rbac_roles_i18n', 'shop_rbac_roles_i18n.id = shop_rbac_roles.id', 'left')
640
            ->where('shop_rbac_roles.id', $roleId)
641
            ->where('shop_rbac_roles_i18n.locale', $locale)
642
            ->get();
643
644
        if ($queryModel === null) {
645
            $this->error404(lang('Role not found'));
646
        }
647
648
        if ($this->input->post()) {
649
650
            $this->form_validation->set_rules('alt_name', lang('Title'), 'required');
651
652
            if ($this->form_validation->run($this) == FALSE) {
653
                showMessage(validation_errors(), '', 'r');
654
            } else {
655
656
                $sql = 'UPDATE shop_rbac_roles SET importance = ' . $this->db->escape($this->input->post('Importance')) .
657
                    " WHERE id   =   '" . $roleId . "'";
658
                $this->db->query($sql);
659
660
                $sqlI = 'UPDATE `shop_rbac_roles_i18n` SET `alt_name` = ' .
661
                    $this->db->escape($this->input->post('alt_name')) . ', `description` = ' .
662
                    $this->db->escape($this->input->post('Description')) . " WHERE id = '" .
663
                    $roleId . "' AND locale = '" . MY_Controller::getCurrentLocale() . "'";
664
                $this->db->query($sqlI);
665
666
                //$this->db->where('id',$roleId)->update('shop_rbac_roles',array('name', $this->input->post('Name')));
667
668
                $privileges = $this->input->post('Privileges') ?: [];
669
                //
670
                //                if (MY_Controller::isProCMS()) {
671
                //                    $privilegesPOSTIds = $this->filterShopPrivileges();
672
                //                } else {
673
                    $privilegesPOSTIds = $privileges;
674
                //                }
675
676
                    $idForDelete = implode(', ', $privilegesPOSTIds);
677
678
                    $sqlDelete = 'DELETE FROM `shop_rbac_roles_privileges` WHERE `role_id`=' . $roleId;
679
680
                    count($privileges) > 0 && $sqlDelete .= ' AND `privilege_id` NOT IN (' . $idForDelete . ')';
681
682
                    $this->db->query($sqlDelete);
683
684
                foreach ($privilegesPOSTIds as $idPrivilege) {
685
                    if (!$this->db->where(['role_id' => $roleId, 'privilege_id' => (int) $idPrivilege])->get(self::$rbac_roles_privileges_table)->num_rows()) {
686
                        $sqlPrivilege = 'INSERT INTO shop_rbac_roles_privileges (role_id, privilege_id) VALUES(' . $this->db->escape($roleId) . ', ' . $this->db->escape($idPrivilege) . ')';
687
                        $this->db->query($sqlPrivilege);
688
                    }
689
                }
690
                $this->lib_admin->log(lang('Role was edited') . '. Id: ' . $roleId);
691
                showMessage(lang('Changes have been saved'));
692
                pjax('/admin/rbac/roleEdit/' . $roleId);
693
                if ($this->input->post('action') != 'edit') {
694
                    pjax('/admin/rbac/roleList');
695
                }
696
            }
697
        } else {
698
699
            $queryPrivilegeR = $this->db->select('privilege_id')
700
                ->from('shop_rbac_roles_privileges')
701
                ->where('role_id', $roleId)
702
                ->get()->result_array();
703
704
            $role_privileges = [];
705
            foreach ($queryPrivilegeR as $item) {
706
                $role_privileges[] = (int) $item['privilege_id'];
707
            }
708
709
            $types = $this->db->select('type')
710
                ->distinct()
711
                ->from(self::$rbac_group_table)
712
                ->get()->result_array();
713
714
            $controller_types = [];
715
716
            foreach ($types as $item) {
717
                $controller_types[] = $item['type'];
718
            }
719
720
            //preparing groups
721
            $locale = MY_Controller::defaultLocale();
722
            $res = $this->db->select('id')->get_where(self::$rbac_group_table . '_i18n', ['locale' => $locale])->result_array();
723
            if (count($res) < 1) {
724
                $locale = 'en';
725
            }
726
727
            $result = self::makeRolesArray($controller_types, $locale);
728
729
            $Lang = $this->db->select('lang_sel')
730
                ->from('settings')
731
                ->get()
732
                ->row();
733
734
            //            dd($result);
735
736
            $this->template->add_array(
737
                [
738
                 'model'          => $queryModel->row(),
739
                 'lang_sel'       => $Lang,
740
                 'types'          => $result,
741
                 'privilegeCheck' => $role_privileges,
742
                ]
743
            );
744
745
            $this->template->show('roleEdit', FALSE);
746
        }
747
    }
748
749
    /**
750
     * display a list of RBAC roles
751
     *
752
     * @access public
753
     * @return    void
754
     */
755
    public static function roleList() {
756
        CI::$APP->template->add_array(
757
            [
758
             'model' => self::getRoles(),
759
            ]
760
        );
761
762
        CI::$APP->template->show('roleList', FALSE);
763
    }
764
765
    /**
766
     * @return mixed
767
     */
768
    public static function getRoles() {
769
        $sql = 'SELECT SRR.id, SRR.name, SRR.importance, SRRI.alt_name, SRRI.description
770
            FROM shop_rbac_roles SRR
771
            INNER JOIN shop_rbac_roles_i18n SRRI ON SRRI.id = SRR.id WHERE SRRI.locale = "' . MY_Controller::getCurrentLocale() . '" ORDER BY SRR.id ASC';
772
        return CI::$APP->db->query($sql)->result();
773
    }
774
775
    /**
776
     * delete a RBAC privileges group
777
     *
778
     * @access public
779
     * @return    void
780
     */
781
    public function roleDelete() {
782
        $groupId = $this->input->post('ids');
783
784
        if ($groupId != null) {
785
            foreach ($groupId as $id) {
786
                $this->db->delete('shop_rbac_roles', ['id' => $id]);
787
                $this->db->delete('shop_rbac_roles_i18n', ['id' => $id]);
788
                $this->db->delete('shop_rbac_roles_privileges', ['role_id' => $id]);
789
            }
790
791
            $this->lib_admin->log(lang('Role was deleted') . '. Id: ' . implode(', ', $groupId));
792
793
            showMessage(lang('Role(s) successfully deleted'));
794
            //            showMessage('Роль(и) успешно удалена(ы)');
795
            pjax('/admin/rbac/roleList');
796
        }
797
    }
798
799
    /*     * *************  RBAC privileges  ************** */
800
801
    /**
802
     * create a RBAC privilege
803
     *
804
     * @access public
805
     * @return    void
806
     */
807
    public function privilegeCreate() {
808
809
        if ($this->input->post()) {
810
811
            $this->form_validation->set_rules('Name', 'Name', 'required');
812
813
            if ($this->form_validation->run($this) == FALSE) {
814
                showMessage(validation_errors(), '', 'r');
815
            } else {
816
817
                $sql = 'INSERT INTO shop_rbac_privileges(name, group_id) VALUES(' . $this->db->escape($this->input->post('Name')) .
818
                    ',  ' . $this->db->escape($this->input->post('GroupId')) . ')';
819
                $this->db->query($sql);
820
821
                $idNewPrivilege = $this->db->insert_id();
822
823
                $sqlI = 'INSERT INTO shop_rbac_privileges_i18n(id, title, description, locale) VALUES('
824
                    . $idNewPrivilege .
825
                    ', ' . $this->db->escape($this->input->post('Title')) .
826
                    ', ' . $this->db->escape($this->input->post('Description')) .
827
                    ", '" . MY_Controller::getCurrentLocale() . "')";
828
                $this->db->query($sqlI);
829
830
                showMessage(lang('Privilege created'));
831
832
                if ($this->input->post('action') == 'close') {
833
                    pjax('/admin/rbac/privilegeCreate');
834
                } else {
835
                    pjax('/admin/rbac/privilegeList');
836
                }
837
            }
838
        } else {
839
            $sql = 'SELECT SRG.id, SRGI.description
840
            FROM shop_rbac_group SRG
841
            INNER JOIN  shop_rbac_group_i18n SRGI ON SRGI.id = SRG.id WHERE SRGI.locale = "' . MY_Controller::getCurrentLocale() . '"';
842
            $queryRBACGroup = $this->db->query($sql)->result();
843
844
            $this->template->add_array(
845
                ['groups' => $queryRBACGroup]
846
            );
847
848
            $this->template->show('privilegeCreate', FALSE);
849
        }
850
    }
851
852
    /**
853
     * edit a RBAC privilege
854
     *
855
     * @param integer $privilegeId
856
     * @access public
857
     * @return    void
858
     */
859
    public function privilegeEdit($privilegeId) {
860
        //        $queryRBACPrivilege = $this->db->get_where('shop_rbac_privileges', array('id' => $privilegeId))->row();
861
862
        $sqlPr = 'SELECT SRP.id, SRP.name, SRP.group_id, SRPI.title, SRPI.description
863
            FROM shop_rbac_privileges SRP
864
            INNER JOIN   shop_rbac_privileges_i18n SRPI ON SRPI.id = SRP.id WHERE SRPI.locale = "' . MY_Controller::getCurrentLocale() . '" AND SRP.id = ' . $privilegeId;
865
        $queryRBACPrivilege = $this->db->query($sqlPr)->row();
866
867
        if ($queryRBACPrivilege === null AND FALSE) {
868
            $this->error404(lang('The privilege is not found'));
869
        }
870
871
        if ($this->input->post()) {
872
873
            $sql = 'UPDATE shop_rbac_privileges SET name = ' . $this->db->escape($this->input->post('Name')) . ',  description  =  ' . $this->db->escape($this->input->post('Description')) . ', group_id = ' . $this->db->escape($this->input->post('GroupId')) .
874
                ' WHERE id = ' . $privilegeId;
875
            $this->db->query($sql);
876
877
            showMessage(lang('Changes have been saved'));
878
879
            if ($this->input->post('action') == 'close') {
880
                pjax('/admin/rbac/privilegeEdit/' . $privilegeId);
881
            } else {
882
                pjax('/admin/rbac/privilegeList');
883
            }
884 View Code Duplication
        } else {
885
            $sql = 'SELECT SRG.id, SRGI.description
886
            FROM shop_rbac_group SRG
887
            INNER JOIN  shop_rbac_group_i18n SRGI ON SRGI.id = SRG.id WHERE SRGI.locale = "' . MY_Controller::getCurrentLocale() . '"';
888
            $queryRBACGroup = $this->db->query($sql)->result();
889
890
            $this->template->add_array(
891
                [
892
                 'model'  => $queryRBACPrivilege,
893
                 'groups' => $queryRBACGroup,
894
                ]
895
            );
896
897
            $this->template->show('privilegeEdit', FALSE);
898
        }
899
    }
900
901
    /**
902
     * display a list of RBAC privileges
903
     *
904
     * @access public
905
     * @return    void
906
     */
907
    public function privilegeList() {
908
909
        $sql = 'SELECT SRG.id, SRG.name, SRGI.description
910
            FROM shop_rbac_group SRG
911
            INNER JOIN shop_rbac_group_i18n SRGI ON SRGI.id = SRG.id WHERE SRGI.locale = "' . MY_Controller::getCurrentLocale() . '"';
912
        $queryGroups = $this->db->query($sql)->result();
913
        foreach ($queryGroups as $key => $value) {
914
            $sqlPriv = 'SELECT SRP.id, SRP.name, SRP.group_id, SRPI.title, SRPI.description
915
            FROM shop_rbac_privileges SRP
916
            INNER JOIN  shop_rbac_privileges_i18n SRPI ON SRPI.id = SRP.id WHERE SRPI.locale = "' . MY_Controller::getCurrentLocale() . '" AND SRP.group_id = ' . $value->id;
917
            $queryGroupsPrivilege = $this->db->query($sqlPriv)->result();
918
919
            $queryGroups[$key]->privileges = $queryGroupsPrivilege;
920
        }
921
922
        $queryRBACGroup = $this->db->select(['id', 'name'])->get('shop_rbac_privileges')->result();
923
924
        $this->template->add_array(
925
            [
926
             'model'  => $queryRBACGroup,
927
             'groups' => $queryGroups,
928
            ]
929
        );
930
931
        $this->template->show('privilegeList', FALSE);
932
    }
933
934
    /**
935
     * delete a RBAC privilege
936
     *
937
     * @access public
938
     * @return    void
939
     */
940
    public function privilegeDelete() {
941
        $privilegeId = $this->input->post('id');
942
        $model = ShopRbacPrivilegesQuery::create()
943
            ->findPks($privilegeId);
944
945
        if ($model != null) {
946
            $model->delete();
947
            showMessage('Успех', 'Привилегии успешно удалены');
948
            pjax('/admin/components/run/shop/rbac/privilege_list');
949
        }
950
    }
951
952
    public static function checkControlPanelAccess($role_id) {
953
        if ($role_id != null) {
954
            $ci = &get_instance();
955
            $r = $ci->db->query(
956
                'SELECT * FROM `' . self::$rbac_roles_privileges_table . '`
957
                        JOIN `' . self::$rbac_privileges_table . '` ON ' . self::$rbac_roles_privileges_table . '.privilege_id = ' . self::$rbac_privileges_table . '.id
958
                        WHERE ' . self::$rbac_roles_privileges_table . '.role_id = ' . $role_id . " AND `name` = 'Admin::__construct'"
959
            )->num_rows();
960
            if ($r > 0) {
961
                return 'admin';
962
            } else {
963
                return '';
964
            }
965
        } else {
966
            return '';
967
        }
968
    }
969
970
    public function deletePermition($id = null) {
971
        if (!$id) {
972
            return false;
973
        } else {
974
            $this->db->where('id', $id)->delete(self::$rbac_privileges_table . '_i18n');
975
            $this->db->where('id', $id)->delete(self::$rbac_privileges_table);
976
            showMessage('Привилегия удалена');
977
            pjax('/admin/rbac/roleEdit/1');
978
        }
979
    }
980
981
    public function makeRolesArray($controller_types, $locale) {
982
        /* @var $ci MY_Controller */
983
        $ci = &get_instance();
984
        foreach ($controller_types as $controller_type) {
985
            $result[$controller_type] = $ci->db->query(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
986
                'SELECT *, ' . self::$rbac_group_table . '.id as id FROM ' . self::$rbac_group_table . '
987
                    LEFT JOIN `' . self::$rbac_group_table . '_i18n` ON ' . self::$rbac_group_table . '.id=' . self::$rbac_group_table . "_i18n.id AND `locale` = '$locale'
988
                        WHERE `type`='$controller_type'"
989
            )->result_array();
990
            if (!empty($result[$controller_type])) {
991
                foreach ($result[$controller_type] as $key => $group) {
992
                    $result[$controller_type][$key]['privileges'] = $ci->db->query(
993
                        'SELECT *, ' . self::$rbac_privileges_table . '.id as id FROM ' . self::$rbac_privileges_table . '
994
                            LEFT JOIN ' . self::$rbac_privileges_table . '_i18n ON ' . self::$rbac_privileges_table . '.id=' . self::$rbac_privileges_table . "_i18n.id AND `locale` = '$locale'
995
                                WHERE `group_id`=" . (int) $group['id']
996
                    )->result_array();
997
                }
998
            }
999
        }
1000
1001
        //array sort
1002
        foreach ($controller_types as $controller_type) {
1003
            //foreach ($result[$controller_type] as $key => $value) {
1004
            $controller_type_count = count($result[$controller_type]);
1005
            for ($j = 0; $j < $controller_type_count; $j++) {
1006
                for ($i = 0; $i < $controller_type_count - $j; $i++) {
1007
                    if ($result[$controller_type][$i + 1]) {
1008
                        if (count($result[$controller_type][$i + 1]['privileges']) < count($result[$controller_type][$i]['privileges'])) {
1009
                            $temp = $result[$controller_type][$i];
1010
                            $result[$controller_type][$i] = $result[$controller_type][$i + 1];
1011
                            $result[$controller_type][$i + 1] = $temp;
1012
                        }
1013
                    }
1014
                }
1015
            }
1016
        }
1017
1018
        return $result;
1019
    }
1020
1021
    private function filterShopPrivileges() {
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
1022
        $privilegesPOST = $this->input->post('Privileges');
1023
        $skipPrivileges = $this->db->like('name', 'Shop')->get('shop_rbac_privileges');
1024
        if ($skipPrivileges) {
1025
            $skipPrivileges = $skipPrivileges->result_array();
1026
            $skipPrivilegesIds = [];
1027
            array_map(
1028
                function ($privilege) use (&$skipPrivilegesIds) {
1029
                    $skipPrivilegesIds[$privilege['id']] = $privilege;
1030
                },
1031
                $skipPrivileges
1032
            );
1033
        }
1034
1035
        $privilegesPOSTIds = array_filter(
1036
            $privilegesPOST,
1037
            function ($id) use (&$skipPrivilegesIds, &$privilegesPOST) {
1038
                return !$skipPrivilegesIds[$id] ? true : false;
1039
            }
1040
        );
1041
        return $privilegesPOSTIds;
1042
    }
1043
1044
    private function error404($message) {
1045
        $this->template->assign('message', $message);
1046
        $this->template->show('404');
1047
        exit;
1048
    }
1049
1050
}