1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
class jugaad extends Controller { |
4
|
|
|
|
5
|
|
|
function __construct() { |
|
|
|
|
6
|
|
|
$this->load_library("http_lib", "http"); |
7
|
|
|
$this->load_library("auth_lib", "auth"); |
8
|
|
|
$this->auth->force_authentication(); |
|
|
|
|
9
|
|
|
|
10
|
|
|
$this->load_model("jugaad_model"); |
11
|
|
|
$this->load_model("template_model"); |
12
|
|
|
$this->load_model("perms_model"); |
13
|
|
|
|
14
|
|
|
$this->user = $this->auth->get_user(); |
|
|
|
|
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
private function is_slug_valid($slug) { |
18
|
|
|
return preg_match('/^[a-z0-9-_]+$/i', $slug); |
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
private function handle_save_file($file) { |
22
|
|
|
if (!empty($_POST["save"]) && isset($_POST["file_id"]) |
23
|
|
|
&& (!empty($_POST["slug"]) || $_POST["file_id"] == 0) |
24
|
|
|
) { |
25
|
|
|
$file_id = $_POST["file_id"]; |
26
|
|
|
$slug = htmlspecialchars(@$_POST["slug"] ?: ""); |
27
|
|
|
$data = @$_POST["data"] ?: array(); |
28
|
|
|
$template = $_POST["template"]; |
29
|
|
|
$version_id = @$_POST["version_id"] ?: 0; |
30
|
|
|
|
31
|
|
|
if ($slug && !$this->is_slug_valid($slug)) { |
32
|
|
|
return "Invalid slug"; |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
$latest_version = $this->jugaad_model->get_latest_version_id($file_id); |
|
|
|
|
36
|
|
|
if ($latest_version > $version_id) { |
37
|
|
|
return "Cannot save. Someone else also edited the file"; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
if ($file["type"] == "file") { |
41
|
|
|
$template_meta = $this->template_model->get_meta($file["template"]); |
|
|
|
|
42
|
|
|
$orig_data = $this->jugaad_model->get_file_data($file_id, $template_meta, $this->user, false); |
43
|
|
|
|
44
|
|
|
// Clean data |
45
|
|
|
foreach ($data as $key => $value) { |
46
|
|
|
if (array_key_exists($key, $orig_data)) { |
47
|
|
|
if ($data[$key] == $orig_data[$key]) { |
48
|
|
|
unset($data[$key]); |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
$save = $this->jugaad_model->update_file($file_id, $slug, $data, $template, $this->user); |
55
|
|
|
if ($save === false) { |
56
|
|
|
return "Could not save file"; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
$path = $this->jugaad_model->get_file_path($file_id); |
60
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path . "?edit"); |
|
|
|
|
61
|
|
|
} else { |
62
|
|
|
return false; |
63
|
|
|
} |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
private function handle_add_file($file) { |
|
|
|
|
67
|
|
|
if (!empty($_POST["add"]) && isset($_POST["parent_id"]) |
68
|
|
|
&& !empty($_POST["slug"]) |
69
|
|
|
) { |
70
|
|
|
$parent_id = $_POST["parent_id"]; |
71
|
|
|
$slug = $_POST["slug"]; |
72
|
|
|
$type = $_POST["type"]; |
73
|
|
|
$template = $_POST["template"]; |
74
|
|
|
$default_role = $_POST["default_role"]; |
75
|
|
|
|
76
|
|
|
if (!$this->is_slug_valid($slug)) { |
77
|
|
|
return "Invalid slug"; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
$add = $this->jugaad_model->new_file($parent_id, $slug, $type, $default_role, $template, $this->user); |
|
|
|
|
81
|
|
|
if ($add === false) { |
82
|
|
|
return "Could not add file"; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$path = $this->jugaad_model->get_file_path($parent_id) . $slug . "/"; |
86
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path . "?edit"); |
|
|
|
|
87
|
|
|
} else { |
88
|
|
|
return false; |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
private function handle_update_default_role($file) { |
|
|
|
|
93
|
|
|
if (!empty($_POST["update_default_role"]) && isset($_POST["file_id"])) { |
94
|
|
|
if (!$this->user_can['manage_user']) { |
95
|
|
|
$this->http->response_code(403); |
|
|
|
|
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$file_id = $_POST["file_id"]; |
99
|
|
|
$default_role = $_POST["default_role"]; |
100
|
|
|
|
101
|
|
|
if (false === $this->perms_model->set_default_role($file_id, $default_role)) { |
|
|
|
|
102
|
|
|
return "Could not update default role"; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
$path = $this->jugaad_model->get_file_path($file_id); |
|
|
|
|
106
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path . "?edit#useredit"); |
107
|
|
|
} else { |
108
|
|
|
return false; |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
private function handle_add_user($file) { |
|
|
|
|
113
|
|
|
if (!empty($_POST["add_user"]) && isset($_POST["file_id"]) |
114
|
|
|
&& !empty($_POST["username"]) |
115
|
|
|
) { |
116
|
|
|
if (!$this->user_can['manage_user']) { |
117
|
|
|
$this->http->response_code(403); |
|
|
|
|
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$file_id = $_POST["file_id"]; |
121
|
|
|
$username = $_POST["username"]; |
122
|
|
|
$role = $_POST["role"]; |
123
|
|
|
|
124
|
|
|
$add = $this->perms_model->add_user_role($file_id, $username, $role); |
|
|
|
|
125
|
|
|
if ($add === false) { |
126
|
|
|
return "Could not add user"; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
$path = $this->jugaad_model->get_file_path($file_id); |
|
|
|
|
130
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path . "?edit#useredit"); |
131
|
|
|
} else { |
132
|
|
|
return false; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
private function handle_revoke_user($file) { |
|
|
|
|
137
|
|
|
if (!empty($_POST["revoke_user"]) && isset($_POST["file_id"]) |
138
|
|
|
&& !empty($_POST["username"]) |
139
|
|
|
) { |
140
|
|
|
if (!$this->user_can['manage_user']) { |
141
|
|
|
$this->http->response_code(403); |
|
|
|
|
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
$file_id = $_POST["file_id"]; |
145
|
|
|
$username = $_POST["username"]; |
146
|
|
|
|
147
|
|
|
$add = $this->perms_model->remove_user_role($file_id, $username); |
|
|
|
|
148
|
|
|
if ($add === false) { |
149
|
|
|
return "Could not revoke permissions for user"; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
$path = $this->jugaad_model->get_file_path($file_id); |
|
|
|
|
153
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path . "?edit#useredit"); |
154
|
|
|
} else { |
155
|
|
|
return false; |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
private function handle_delete_file($file) { |
|
|
|
|
160
|
|
|
if (!empty($_POST["delete_file"]) && isset($_POST["file_id"])) { |
161
|
|
|
$file_id = $_POST["file_id"]; |
162
|
|
|
$file = $this->jugaad_model->get_file($file_id); |
|
|
|
|
163
|
|
|
$parent_id = @$file['parent'] ?: 0; |
164
|
|
|
$file_type = @$file['type'] ?: false; |
165
|
|
|
|
166
|
|
|
if ($file_type == 'directory') { |
167
|
|
|
$file_list = $this->jugaad_model->get_directory($file_id); |
168
|
|
|
if (count($file_list)) { |
169
|
|
|
return "Cannot delete non-empty directory"; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
$delete = $this->jugaad_model->delete_file($file_id, $this->user); |
174
|
|
|
if ($delete === false) { |
175
|
|
|
return "Could not delete " . $file_type; |
|
|
|
|
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
$path = $this->jugaad_model->get_file_path($parent_id); |
179
|
|
|
$this->http->redirect(base_url() . "jugaad" . $path); |
|
|
|
|
180
|
|
|
} else { |
181
|
|
|
return false; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
private function show_file_edit($file) { |
186
|
|
|
$file["template_meta"] = $this->template_model->get_meta($file["template"]); |
|
|
|
|
187
|
|
|
$file["data"] = $this->jugaad_model->get_file_data($file['id'], $file["template_meta"], $this->user, false); |
|
|
|
|
188
|
|
|
$file["path"] = $this->jugaad_model->get_file_path($file['id']); |
189
|
|
|
|
190
|
|
|
$this->load_view("file_edit", $file); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
private function handle_edit_action($file) { |
194
|
|
|
return $this->handle_save_file($file) |
195
|
|
|
?: $this->handle_add_file($file) |
196
|
|
|
?: $this->handle_update_default_role($file) |
197
|
|
|
?: $this->handle_add_user($file) |
198
|
|
|
?: $this->handle_revoke_user($file) |
199
|
|
|
?: $this->handle_delete_file($file); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
private function handle_edit($file_id, $file) { |
203
|
|
|
if (!$this->user_can['write_file']) { |
204
|
|
|
$this->http->response_code(403); |
|
|
|
|
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
$file_type = $file ? $file['type'] : false; |
208
|
|
|
|
209
|
|
|
$error = $this->handle_edit_action($file); |
210
|
|
|
|
211
|
|
|
$file["error"] = $error; |
212
|
|
|
$file["admins"] = $this->perms_model->get_user_list($file_id); |
|
|
|
|
213
|
|
|
$file["user"] = $this->user; |
214
|
|
|
$file["user_can"] = $this->user_can; |
215
|
|
|
$file["version_id"] = $this->jugaad_model->get_latest_version_id($file_id); |
|
|
|
|
216
|
|
|
|
217
|
|
|
$file["templates"] = $this->template_model->get_template_list(); |
|
|
|
|
218
|
|
|
|
219
|
|
|
if ($file_type == "directory") { |
220
|
|
|
$this->load_view("directory_edit", $file); |
221
|
|
|
} elseif ($file_type == "file") { |
222
|
|
|
$this->show_file_edit($file); |
223
|
|
|
} else { |
224
|
|
|
$this->http->response_code(404); |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
private function handle_history($file_id, $file) { |
229
|
|
|
if (!$this->user_can['read_file']) { |
230
|
|
|
$this->http->response_code(403); |
|
|
|
|
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
$file_type = $file ? $file['type'] : false; |
234
|
|
|
|
235
|
|
|
if ($file_type == "file") { |
236
|
|
|
$file["history"] = $this->jugaad_model->get_history($file_id); |
|
|
|
|
237
|
|
|
|
238
|
|
|
$file["user_can"] = $this->user_can; |
239
|
|
|
if ($this->user_can["see_history_detail"] && isset($_GET["id"])) { |
240
|
|
|
$edit_id = $_GET["id"]; |
241
|
|
|
foreach ($file["history"] as $value) { |
242
|
|
|
if ($value["id"] == $edit_id) { |
243
|
|
|
$file["history_item"] = $value; |
244
|
|
|
break; |
245
|
|
|
} |
246
|
|
|
} |
247
|
|
|
} elseif (isset($_GET["id"])) { |
248
|
|
|
$file["perm_error"] = true; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
$this->load_view("file_history", $file); |
252
|
|
|
} else { |
253
|
|
|
$this->http->response_code(404); |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
private function handle_read($file_id, $file) { |
258
|
|
|
if (!$this->user_can['read_file']) { |
259
|
|
|
$this->http->response_code(403); |
|
|
|
|
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$file_type = $file ? $file['type'] : false; |
263
|
|
|
|
264
|
|
|
if ($file_type == "directory") { |
265
|
|
|
$file["data"] = $this->jugaad_model->get_directory($file_id); |
|
|
|
|
266
|
|
|
$file["user_can"] = $this->user_can; |
267
|
|
|
$this->load_view("directory", $file); |
268
|
|
|
} elseif ($file_type == "file") { |
269
|
|
|
$this->http->redirect('?edit'); |
270
|
|
|
} else { |
271
|
|
|
$this->http->response_code(404); |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
function read() { |
|
|
|
|
276
|
|
|
$path = func_get_args(); |
277
|
|
|
|
278
|
|
|
$action = false; |
279
|
|
|
if (isset($_GET["edit"])) { |
280
|
|
|
$action = "edit"; |
281
|
|
|
} elseif (isset($_GET["history"])) { |
282
|
|
|
$action = "history"; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
$file_id = $this->jugaad_model->get_path_id($path); |
|
|
|
|
286
|
|
|
if ($file_id === false) { |
287
|
|
|
$this->http->response_code(404); |
|
|
|
|
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
$file = $this->jugaad_model->get_file($file_id); |
291
|
|
|
|
292
|
|
|
$this->user_can = $this->perms_model->get_permissions($file_id, $this->user); |
|
|
|
|
293
|
|
|
|
294
|
|
|
if ($action == 'edit') { |
295
|
|
|
$this->handle_edit($file_id, $file); |
296
|
|
|
} elseif ($action == 'history') { |
297
|
|
|
$this->handle_history($file_id, $file); |
298
|
|
|
} else { |
299
|
|
|
$this->handle_read($file_id, $file); |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
function trash() { |
|
|
|
|
304
|
|
|
$user_can = $this->perms_model->get_permissions(0, $this->user); |
|
|
|
|
305
|
|
|
if (!$user_can['see_global_trash']) { |
306
|
|
|
$this->http->response_code(403); |
|
|
|
|
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
$error = ""; |
310
|
|
|
$msg = ""; |
311
|
|
|
if (!empty($_POST["restore_file"]) && isset($_POST["file_id"])) { |
312
|
|
|
$file_id = $_POST["file_id"]; |
313
|
|
|
$recovered = $this->jugaad_model->recover_file($file_id, $this->user); |
|
|
|
|
314
|
|
|
if ($recovered === false) { |
315
|
|
|
$error = "Could not recover file"; |
316
|
|
|
} else { |
317
|
|
|
$_SESSION['recovered_file'] = $file_id; |
318
|
|
|
$this->http->redirect(base_url() . "trash/"); |
319
|
|
|
} |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
if (isset($_SESSION['recovered_file'])) { |
323
|
|
|
$file_id = $_SESSION['recovered_file']; |
324
|
|
|
unset($_SESSION['recovered_file']); |
325
|
|
|
|
326
|
|
|
$file = $this->jugaad_model->get_file($file_id); |
327
|
|
|
if ($file !== false) { |
328
|
|
|
$msg = ucfirst($file['type']) . ' recovered. See <a href="' |
329
|
|
|
. base_url() . 'jugaad' . $this->jugaad_model->get_file_path($file['id']) |
330
|
|
|
. '"> recovered ' |
331
|
|
|
. $file['type'] . '</a>.'; |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
$trash_list = $this->jugaad_model->get_trash_list(); |
336
|
|
|
$this->load_view('trash', [ |
337
|
|
|
'files' => $trash_list, |
338
|
|
|
'error' => $error, |
339
|
|
|
'msg' => $msg |
340
|
|
|
]); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
} |
344
|
|
|
|
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.