1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace App\Lib\Repair;
13:
14: use Nette\Object,
15: App\Lib\Table,
16: App\Lib\Tree,
17: App\Model\Database,
18: App\Lib\Statics\Cons;
19:
20: 21: 22:
23: class Repair extends Object {
24:
25: private $database;
26: private $resources;
27: private $roles;
28: private $privileges;
29:
30: public function __construct(Database $database) {
31: $this->database = $database;
32: $this->resources = new Tree(Cons::TABLE_ACL . '_' . Cons::TABLE_RESOURCES, $this->database);
33: $this->roles = new Tree(Cons::TABLE_ACL . '_' . Cons::TABLE_ROLES, $this->database);
34: $this->privileges = new Table(Cons::TABLE_ACL, $this->database);
35: }
36:
37: public function repairSources() {
38: $this->rebuildTables();
39: $this->rebuildMenu();
40: $this->admin();
41: $this->user();
42: return true;
43: }
44:
45: 46: 47:
48: public function rebuildTables() {
49: $tables = (new Table(Cons::TABLE_TABLE, $this->database))->data;
50: $sectionRow = $this->section(Cons::RES_TABLES, 1);
51: foreach ($tables as $tableRow) {
52: $resourceTableRow = $this->section($tableRow[Cons::COLUMN_OBJECT], 2, $sectionRow[Cons::COLUMN_ID]);
53: $this->subsection($tableRow, $resourceTableRow);
54: }
55: }
56:
57: 58: 59:
60: public function rebuildMenu() {
61: $menu = (new Tree(Cons::TABLE_MENU, $this->database))->data->where(Cons::COLUMN_DEPTH, 1);
62: $sectionRow = $this->section(Cons::RES_MENU, 1);
63: foreach ($menu as $menuRow) {
64: $itemRow = $this->section($menuRow[Cons::COLUMN_NAME], 2, $sectionRow[Cons::COLUMN_ID]);
65: $this->recurse($menuRow, $itemRow, Cons::TABLE_MENU);
66: }
67: }
68:
69:
70: 71: 72:
73: public function user() {
74: $role = $this->getRole('User');
75: $tableResource = $this->resources->copy->where(Cons::COLUMN_PATH . ' LIKE ? OR path LIKE ?', 'tables > users %', 'menu > %user% %');
76: foreach ($tableResource as $resource) {
77: if ($resource[Cons::COLUMN_PATH] === 'tables > users > state' || \Nette\Utils\Strings::startsWith($resource[Cons::COLUMN_PATH], 'menu')) {
78: $this->repairPrivilege($role[Cons::COLUMN_ID], $resource[Cons::COLUMN_ID]);
79: } else {
80: $this->repairPrivilege($role[Cons::COLUMN_ID], $resource[Cons::COLUMN_ID], TRUE);
81: }
82: }
83: }
84:
85: 86: 87:
88: public function admin() {
89: $role = $this->getRole('Admin');
90: $tableResource = $this->resources->data;
91: foreach ($tableResource as $resource) {
92: if (\Nette\Utils\Strings::startsWith($resource[Cons::COLUMN_PATH], 'menu')){
93: $this->repairPrivilege($role[Cons::COLUMN_ID], $resource[Cons::COLUMN_ID], FALSE);
94: }else {
95: $this->repairPrivilege($role[Cons::COLUMN_ID], $resource[Cons::COLUMN_ID], TRUE);
96: }
97:
98: }
99: }
100:
101: 102: 103: 104: 105: 106:
107: private function recurse($activeRow, $parent, $table) {
108: $related = $activeRow->related($table . '.' . Cons::COLUMN_PARENT);
109: $depth = $parent[Cons::COLUMN_DEPTH] + 1;
110: foreach ($related as $relatedRow) {
111: $resourceRow = $this->section($relatedRow[Cons::COLUMN_NAME], $depth, $parent[Cons::COLUMN_ID]);
112: $this->recurse($relatedRow, $resourceRow, $table);
113: }
114: }
115:
116: 117: 118: 119:
120: private function subsection($tableRow, $resourceTableRow) {
121: $related = $tableRow->related(Cons::TABLE_TABLE . '_' . Cons::TABLE_FIELDS);
122: foreach ($related as $activeRow) {
123: $this->section(
124: $activeRow[Cons::COLUMN_FIELD], 3, $resourceTableRow[Cons::COLUMN_ID]
125: );
126: }
127: }
128:
129: 130: 131: 132: 133: 134: 135: 136:
137: private function section($section, $depth, $parent = NULL) {
138: return ($this->getSection($section, $depth, $parent))? :
139: $this->setSection($section, $parent);
140: }
141:
142: 143: 144: 145: 146: 147: 148:
149: private function getSection($section, $depth, $parent = NULL) {
150: $ret = $this->resources->copy
151: ->where(Cons::COLUMN_NAME, $section)
152: ->where(Cons::COLUMN_DEPTH, $depth);
153: ($parent === NULL) ? : $ret->where(Cons::COLUMN_PARENT, $parent);
154: return $ret->fetch();
155: }
156:
157: 158: 159: 160: 161: 162:
163: private function setSection($section, $parent) {
164: return $this->resources->insert(array(
165: Cons::COLUMN_NAME => $section,
166: Cons::COLUMN_PARENT => $parent
167: ));
168: }
169:
170: 171: 172: 173: 174:
175: public function getRole($role) {
176: $query = $this->roles->copy->where(Cons::COLUMN_NAME . ' =?', $role)->fetch();
177: if ($query === FALSE) {
178: $query = $this->roles->data->insert(array(
179: Cons::COLUMN_NAME => $role,
180: Cons::COLUMN_PARENT => $this->roles->copy->where(Cons::COLUMN_NAME . ' =?', Cons::ROOT)->fetch()->id
181: ));
182: }
183: return $query;
184: }
185:
186: 187: 188: 189: 190: 191:
192: private function getPrivilege($role, $resource) {
193: $ret = $this->privileges->copy
194: ->where(Cons::TABLE_ACL . '_' . Cons::TABLE_ROLES . '_' . Cons::COLUMN_ID, $role)
195: ->where(Cons::TABLE_ACL . '_' . Cons::TABLE_RESOURCES . '_' . Cons::COLUMN_ID, $resource);
196: return $ret->fetch();
197: }
198: 199: 200: 201: 202: 203:
204: private function repairPrivilege($role, $resource, $all = FALSE) {
205: $privilege = $this->getPrivilege($role, $resource);
206: if ($privilege instanceof \Nette\Database\Table\ActiveRow) {
207: if ($all === FALSE && $privilege[Cons::READ] != '1') {
208: $privilege->update($this->defPriv($role, $resource, $all));
209: }else if($all === TRUE){
210: ($privilege[Cons::READ] == '1' && $privilege[Cons::CREATE] == '1' && $privilege[Cons::WRITE] == '1' && $privilege[Cons::DELETE] == '1')? :
211: $privilege->update($this->defPriv($role, $resource, $all));
212: }
213: } else {
214: $this->privileges->data->insert($this->defPriv($role, $resource, $all));
215: }
216: }
217: 218: 219: 220: 221: 222: 223:
224: private function defPriv($role, $resource, $all = FALSE) {
225: return array(
226: Cons::TABLE_ACL . '_' . Cons::TABLE_ROLES . '_' . Cons::COLUMN_ID => $role,
227: Cons::TABLE_ACL . '_' . Cons::TABLE_RESOURCES . '_' . Cons::COLUMN_ID => $resource,
228: Cons::CREATE => ($all) ? 1 : 0,
229: Cons::WRITE => ($all) ? 1 : 0,
230: Cons::DELETE => ($all) ? 1 : 0,
231: Cons::READ => 1,
232: Cons::COLUMN_C_ID => 1,
233: Cons::COLUMN_W_ID => 1,
234: );
235: }
236: }
237: