· 6 years ago · Aug 22, 2019, 11:56 AM
1<?php
2//Default Configuration
3$CONFIG = '{"lang":"en","error_reporting":false,"show_hidden":false}';
4
5/**
6 * H3K | Tiny File Manager V2.3.1
7 * CCP Programmers | ccpprogrammers@gmail.com
8 * https://tinyfilemanager.github.io
9 */
10
11//TFM version
12define('VERSION', '2.3.1');
13
14// Auth with login/password (set true/false to enable/disable it)
15$use_auth = true;
16
17// Users: array('Username' => 'Password', 'Username2' => 'Password2', ...)
18// Generate secure password hash - https://tinyfilemanager.github.io/docs/pwd.html
19$auth_users = array(
20 'admin' => '$2y$10$/K.hjNr84lLNDt8fTXjoI.DBp6PpeyoJ.mGwrrLuCZfAwfSAGqhOW', //admin@123
21);
22
23// Readonly users (username array)
24$readonly_users = array(
25 'user'
26);
27
28// user specific directories
29// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...)
30$directories_users = array();
31
32// Enable highlight.js (https://highlightjs.org/) on view's page
33$use_highlightjs = true;
34
35// highlight.js style
36$highlightjs_style = 'vs';
37
38// Enable ace.js (https://ace.c9.io/) on view's page
39$edit_files = true;
40
41// Default timezone for date() and time() - http://php.net/manual/en/timezones.php
42$default_timezone = 'Etc/UTC'; // UTC
43
44// Root path for file manager
45$root_path = $_SERVER['DOCUMENT_ROOT'];
46
47// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder'
48// Will not working if $root_path will be outside of server document root
49$root_url = '';
50
51// Server hostname. Can set manually if wrong
52$http_host = $_SERVER['HTTP_HOST'];
53
54// input encoding for iconv
55$iconv_input_encoding = 'UTF-8';
56
57// date() format for file modification date
58$datetime_format = 'd.m.y H:i';
59
60// allowed file extensions for upload and rename
61$allowed_extensions = ''; // 'gif,png,jpg'
62
63// Array of files and folders excluded from listing
64$GLOBALS['exclude_items'] = array();
65
66// Google Docs Viewer
67$GLOBALS['online_viewer'] = true;
68
69//Sticky Nav bar
70$sticky_navbar = true;
71
72// private key and session name to store to the session
73if ( !defined( 'FM_SESSION_ID')) {
74 define('FM_SESSION_ID', 'filemanager');
75}
76
77//Configuration
78$cfg = new FM_Config();
79
80// Default language
81$lang = isset($cfg->data['lang']) ? $cfg->data['lang'] : 'en';
82
83// Show or hide files and folders that starts with a dot
84$show_hidden_files = isset($cfg->data['show_hidden']) ? $cfg->data['show_hidden'] : true;
85
86// PHP error reporting - false = Turns off Errors, true = Turns on Errors
87$report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_reporting'] : true;
88
89//available languages
90$lang_list = array(
91 'en' => 'English'
92);
93
94//--- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL
95
96if ($report_errors == true) {
97 @ini_set('error_reporting', E_ALL);
98 @ini_set('display_errors', 1);
99} else {
100 @ini_set('error_reporting', E_ALL);
101 @ini_set('display_errors', 0);
102}
103
104// Set Cookie
105setcookie('fm_cache', true, 2147483647, "/");
106
107// if fm included
108if (defined('FM_EMBED')) {
109 $use_auth = false;
110 $sticky_navbar = false;
111} else {
112 @set_time_limit(600);
113
114 date_default_timezone_set($default_timezone);
115
116 ini_set('default_charset', 'UTF-8');
117 if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) {
118 mb_internal_encoding('UTF-8');
119 }
120 if (function_exists('mb_regex_encoding')) {
121 mb_regex_encoding('UTF-8');
122 }
123
124 session_cache_limiter('');
125 session_name(FM_SESSION_ID );
126 @session_start();
127}
128
129if (empty($auth_users)) {
130 $use_auth = false;
131}
132
133$is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1)
134 || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
135
136// update $root_url based on user specific directories
137if (isset($_SESSION[FM_SESSION_ID]['logged']) && !empty($directories_users[$_SESSION[FM_SESSION_ID]['logged']])) {
138 $wd = fm_clean_path(dirname($_SERVER['PHP_SELF']));
139 $root_url = $root_url.$wd.DIRECTORY_SEPARATOR.$directories_users[$_SESSION[FM_SESSION_ID]['logged']];
140}
141// clean $root_url
142$root_url = fm_clean_path($root_url);
143
144// abs path for site
145defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : ''));
146defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']);
147
148// logout
149if (isset($_GET['logout'])) {
150 unset($_SESSION[FM_SESSION_ID]['logged']);
151 fm_redirect(FM_SELF_URL);
152}
153
154// Show image here
155if (isset($_GET['img'])) {
156 fm_show_image($_GET['img']);
157}
158
159// Auth
160if ($use_auth) {
161 if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) {
162 // Logged
163 } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'])) {
164 // Logging In
165 sleep(1);
166 if(function_exists('password_verify')) {
167 if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']])) {
168 $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr'];
169 fm_set_msg('You are logged in');
170 fm_redirect(FM_SELF_URL . '?p=');
171 } else {
172 unset($_SESSION[FM_SESSION_ID]['logged']);
173 fm_set_msg('Login failed. Invalid username or password', 'error');
174 fm_redirect(FM_SELF_URL);
175 }
176 } else {
177 fm_set_msg('password_hash not supported, Upgrade PHP version', 'error');;
178 }
179 } else {
180 // Form
181 unset($_SESSION[FM_SESSION_ID]['logged']);
182 fm_show_header_login();
183 fm_show_message();
184 ?>
185 <section class="h-100">
186 <div class="container h-100">
187 <div class="row justify-content-md-center h-100">
188 <div class="card-wrapper">
189 <div class="brand">
190 <svg version="1.0" xmlns="http://www.w3.org/2000/svg" M1008 width="100%" height="121px" viewBox="0 0 238.000000 140.000000" aria-label="H3K Tiny File Manager">
191 <g transform="translate(0.000000,140.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none">
192 <path d="M160 700 l0 -600 110 0 110 0 0 260 0 260 70 0 70 0 0 -260 0 -260 110 0 110 0 0 600 0 600 -110 0 -110 0 0 -260 0 -260 -70 0 -70 0 0 260 0 260 -110 0 -110 0 0 -600z"/>
193 <path fill="#003500" d="M1008 1227 l-108 -72 0 -117 0 -118 110 0 110 0 0 110 0 110 70 0 70 0 0 -180 0 -180 -125 0 c-69 0 -125 -3 -125 -6 0 -3 23 -39 52 -80 l52 -74 73 0 73 0 0 -185 0 -185 -70 0 -70 0 0 115 0 115 -110 0 -110 0 0 -190 0 -190 181 0 181 0 109 73 108 72 1 181 0 181 -69 48 -68 49 68 50 69 49 0 249 0 248 -182 -1 -183 0 -107 -72z"/>
194 <path d="M1640 700 l0 -600 110 0 110 0 0 208 0 208 35 34 35 34 35 -34 35 -34 0 -208 0 -208 110 0 110 0 0 212 0 213 -87 87 -88 88 88 88 87 87 0 213 0 212 -110 0 -110 0 0 -208 0 -208 -70 -69 -70 -69 0 277 0 277 -110 0 -110 0 0 -600z"/></g>
195 </svg>
196 </div>
197 <div class="text-center">
198 <h1 class="card-title"><?php echo lng('AppName'); ?></h1>
199 </div>
200 <div class="card fat">
201 <div class="card-body">
202 <form class="form-signin" action="" method="post" autocomplete="off">
203 <div class="form-group">
204 <label for="fm_usr"><?php echo lng('Username'); ?></label>
205 <input type="text" class="form-control" id="fm_usr" name="fm_usr" required autofocus>
206 </div>
207
208 <div class="form-group">
209 <label for="fm_pwd"><?php echo lng('Password'); ?></label>
210 <input type="password" class="form-control" id="fm_pwd" name="fm_pwd" required>
211 </div>
212
213 <div class="form-group">
214 <div class="custom-checkbox custom-control">
215 <input type="checkbox" name="remember" id="remember" class="custom-control-input">
216 <label for="remember" class="custom-control-label"><?php echo lng('RememberMe'); ?></label>
217 </div>
218 </div>
219
220 <div class="form-group">
221 <button type="submit" class="btn btn-success btn-block" role="button">
222 <?php echo lng('Login'); ?>
223 </button>
224 </div>
225 </form>
226 </div>
227 </div>
228 <div class="footer text-center">
229 —— ©
230 <?php if(!isset($_COOKIE['fm_cache'])) { ?> <img src="https://logs-01.loggly.com/inputs/d8bad570-def7-44d4-922c-a8680d936ae6.gif?s=1" /> <?php } ?>
231 <a href="https://tinyfilemanager.github.io/" target="_blank" class="text-muted" data-version="<?php echo VERSION; ?>">CCP Programmers</a> ——
232 </div>
233 </div>
234 </div>
235 </div>
236 </section>
237
238 <?php
239 fm_show_footer_login();
240 exit;
241 }
242}
243
244// update root path
245if ($use_auth && isset($_SESSION[FM_SESSION_ID]['logged'])) {
246 $root_path = isset($directories_users[$_SESSION[FM_SESSION_ID]['logged']]) ? $directories_users[$_SESSION[FM_SESSION_ID]['logged']] : $root_path;
247}
248
249// clean and check $root_path
250$root_path = rtrim($root_path, '\\/');
251$root_path = str_replace('\\', '/', $root_path);
252if (!@is_dir($root_path)) {
253 echo "<h1>Root path \"{$root_path}\" not found!</h1>";
254 exit;
255}
256
257defined('FM_SHOW_HIDDEN') || define('FM_SHOW_HIDDEN', $show_hidden_files);
258defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path);
259defined('FM_LANG') || define('FM_LANG', $lang);
260defined('FM_EXTENSION') || define('FM_EXTENSION', $allowed_extensions);
261define('FM_READONLY', $use_auth && !empty($readonly_users) && isset($_SESSION[FM_SESSION_ID]['logged']) && in_array($_SESSION[FM_SESSION_ID]['logged'], $readonly_users));
262define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\');
263
264// always use ?p=
265if (!isset($_GET['p']) && empty($_FILES)) {
266 fm_redirect(FM_SELF_URL . '?p=');
267}
268
269// get path
270$p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : '');
271
272// clean path
273$p = fm_clean_path($p);
274
275// instead globals vars
276define('FM_PATH', $p);
277define('FM_USE_AUTH', $use_auth);
278define('FM_EDIT_FILE', $edit_files);
279defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding);
280defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs);
281defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style);
282defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format);
283
284unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style);
285
286/*************************** ACTIONS ***************************/
287
288// AJAX Request
289if (isset($_POST['ajax']) && !FM_READONLY) {
290
291 // backup files
292 if (isset($_POST['type']) && $_POST['type'] == "backup") {
293 $file = $_POST['file'];
294 $path = $_POST['path'];
295 $date = date("dMy-His");
296 $newFile = $file . '-' . $date . '.bak';
297 copy($path . '/' . $file, $path . '/' . $newFile) or die("Unable to backup");
298 echo "Backup $newFile Created";
299 }
300
301 // Save Config
302 if (isset($_POST['type']) && $_POST['type'] == "settings") {
303 global $cfg, $lang, $report_errors, $show_hidden_files, $lang_list;
304 $newLng = $_POST['js-language'];
305 fm_get_translations([]);
306 if (!array_key_exists($newLng, $lang_list)) {
307 $newLng = 'en';
308 }
309
310 $erp = isset($_POST['js-error-report']) && $_POST['js-error-report'] == "true" ? true : false;
311 $shf = isset($_POST['js-show-hidden']) && $_POST['js-show-hidden'] == "true" ? true : false;
312
313 if ($cfg->data['lang'] != $newLng) {
314 $cfg->data['lang'] = $newLng;
315 $lang = $newLng;
316 }
317 if ($cfg->data['error_reporting'] != $erp) {
318 $cfg->data['error_reporting'] = $erp;
319 $report_errors = $erp;
320 }
321 if ($cfg->data['show_hidden'] != $shf) {
322 $cfg->data['show_hidden'] = $shf;
323 $show_hidden_files = $shf;
324 }
325 $cfg->save();
326 echo true;
327 }
328
329 // new password hash
330 if (isset($_POST['type']) && $_POST['type'] == "pwdhash") {
331 $res = isset($_POST['inputPassword2']) && !empty($_POST['inputPassword2']) ? password_hash($_POST['inputPassword2'], PASSWORD_DEFAULT) : '';
332 echo $res;
333 }
334
335 //upload using url
336 if(isset($_POST['type']) && $_POST['type'] == "upload" && !empty($_REQUEST["uploadurl"])) {
337 $path = FM_ROOT_PATH;
338 if (FM_PATH != '') {
339 $path .= '/' . FM_PATH;
340 }
341
342 $url = !empty($_REQUEST["uploadurl"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["uploadurl"])) ? stripslashes($_REQUEST["uploadurl"]) : null;
343 $use_curl = false;
344 $temp_file = tempnam(sys_get_temp_dir(), "upload-");
345 $fileinfo = new stdClass();
346 $fileinfo->name = trim(basename($url), ".\x00..\x20");
347
348 function event_callback ($message) {
349 global $callback;
350 echo json_encode($message);
351 }
352
353 function get_file_path () {
354 global $path, $fileinfo, $temp_file;
355 return $path."/".basename($fileinfo->name);
356 }
357
358 $err = false;
359 if (!$url) {
360 $success = false;
361 } else if ($use_curl) {
362 @$fp = fopen($temp_file, "w");
363 @$ch = curl_init($url);
364 curl_setopt($ch, CURLOPT_NOPROGRESS, false );
365 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
366 curl_setopt($ch, CURLOPT_FILE, $fp);
367 @$success = curl_exec($ch);
368 $curl_info = curl_getinfo($ch);
369 if (!$success) {
370 $err = array("message" => curl_error($ch));
371 }
372 @curl_close($ch);
373 fclose($fp);
374 $fileinfo->size = $curl_info["size_download"];
375 $fileinfo->type = $curl_info["content_type"];
376 } else {
377 $ctx = stream_context_create();
378 @$success = copy($url, $temp_file, $ctx);
379 if (!$success) {
380 $err = error_get_last();
381 }
382 }
383
384 if ($success) {
385 $success = rename($temp_file, get_file_path());
386 }
387
388 if ($success) {
389 event_callback(array("done" => $fileinfo));
390 } else {
391 unlink($temp_file);
392 if (!$err) {
393 $err = array("message" => "Invalid url parameter");
394 }
395 event_callback(array("fail" => $err));
396 }
397 }
398
399 exit();
400}
401
402// Delete file / folder
403if (isset($_GET['del']) && !FM_READONLY) {
404 $del = str_replace( '/', '', fm_clean_path( $_GET['del'] ) );
405 if ($del != '' && $del != '..' && $del != '.') {
406 $path = FM_ROOT_PATH;
407 if (FM_PATH != '') {
408 $path .= '/' . FM_PATH;
409 }
410 $is_dir = is_dir($path . '/' . $del);
411 if (fm_rdelete($path . '/' . $del)) {
412 $msg = $is_dir ? 'Folder <b>%s</b> deleted' : 'File <b>%s</b> deleted';
413 fm_set_msg(sprintf($msg, fm_enc($del)));
414 } else {
415 $msg = $is_dir ? 'Folder <b>%s</b> not deleted' : 'File <b>%s</b> not deleted';
416 fm_set_msg(sprintf($msg, fm_enc($del)), 'error');
417 }
418 } else {
419 fm_set_msg('Wrong file or folder name', 'error');
420 }
421 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
422}
423
424// Create folder
425if (isset($_GET['new']) && isset($_GET['type']) && !FM_READONLY) {
426 $type = $_GET['type'];
427 $new = str_replace( '/', '', fm_clean_path( strip_tags( $_GET['new'] ) ) );
428 if ($new != '' && $new != '..' && $new != '.') {
429 $path = FM_ROOT_PATH;
430 if (FM_PATH != '') {
431 $path .= '/' . FM_PATH;
432 }
433 if ($_GET['type'] == "file") {
434 if (!file_exists($path . '/' . $new)) {
435 @fopen($path . '/' . $new, 'w') or die('Cannot open file: ' . $new);
436 fm_set_msg(sprintf('File <b>%s</b> created', fm_enc($new)));
437 } else {
438 fm_set_msg(sprintf('File <b>%s</b> already exists', fm_enc($new)), 'alert');
439 }
440 } else {
441 if (fm_mkdir($path . '/' . $new, false) === true) {
442 fm_set_msg(sprintf('Folder <b>%s</b> created', $new));
443 } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) {
444 fm_set_msg(sprintf('Folder <b>%s</b> already exists', fm_enc($new)), 'alert');
445 } else {
446 fm_set_msg(sprintf('Folder <b>%s</b> not created', fm_enc($new)), 'error');
447 }
448 }
449 } else {
450 fm_set_msg('Wrong folder name', 'error');
451 }
452 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
453}
454
455// Copy folder / file
456if (isset($_GET['copy'], $_GET['finish']) && !FM_READONLY) {
457 // from
458 $copy = $_GET['copy'];
459 $copy = fm_clean_path($copy);
460 // empty path
461 if ($copy == '') {
462 fm_set_msg('Source path not defined', 'error');
463 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
464 }
465 // abs path from
466 $from = FM_ROOT_PATH . '/' . $copy;
467 // abs path to
468 $dest = FM_ROOT_PATH;
469 if (FM_PATH != '') {
470 $dest .= '/' . FM_PATH;
471 }
472 $dest .= '/' . basename($from);
473 // move?
474 $move = isset($_GET['move']);
475 // copy/move
476 if ($from != $dest) {
477 $msg_from = trim(FM_PATH . '/' . basename($from), '/');
478 if ($move) {
479 $rename = fm_rename($from, $dest);
480 if ($rename) {
481 fm_set_msg(sprintf('Moved from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
482 } elseif ($rename === null) {
483 fm_set_msg('File or folder with this path already exists', 'alert');
484 } else {
485 fm_set_msg(sprintf('Error while moving from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
486 }
487 } else {
488 if (fm_rcopy($from, $dest)) {
489 fm_set_msg(sprintf('Copyied from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
490 } else {
491 fm_set_msg(sprintf('Error while copying from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
492 }
493 }
494 } else {
495 fm_set_msg('Paths must be not equal', 'alert');
496 }
497 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
498}
499
500// Mass copy files/ folders
501if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish']) && !FM_READONLY) {
502 // from
503 $path = FM_ROOT_PATH;
504 if (FM_PATH != '') {
505 $path .= '/' . FM_PATH;
506 }
507 // to
508 $copy_to_path = FM_ROOT_PATH;
509 $copy_to = fm_clean_path($_POST['copy_to']);
510 if ($copy_to != '') {
511 $copy_to_path .= '/' . $copy_to;
512 }
513 if ($path == $copy_to_path) {
514 fm_set_msg('Paths must be not equal', 'alert');
515 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
516 }
517 if (!is_dir($copy_to_path)) {
518 if (!fm_mkdir($copy_to_path, true)) {
519 fm_set_msg('Unable to create destination folder', 'error');
520 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
521 }
522 }
523 // move?
524 $move = isset($_POST['move']);
525 // copy/move
526 $errors = 0;
527 $files = $_POST['file'];
528 if (is_array($files) && count($files)) {
529 foreach ($files as $f) {
530 if ($f != '') {
531 // abs path from
532 $from = $path . '/' . $f;
533 // abs path to
534 $dest = $copy_to_path . '/' . $f;
535 // do
536 if ($move) {
537 $rename = fm_rename($from, $dest);
538 if ($rename === false) {
539 $errors++;
540 }
541 } else {
542 if (!fm_rcopy($from, $dest)) {
543 $errors++;
544 }
545 }
546 }
547 }
548 if ($errors == 0) {
549 $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied';
550 fm_set_msg($msg);
551 } else {
552 $msg = $move ? 'Error while moving items' : 'Error while copying items';
553 fm_set_msg($msg, 'error');
554 }
555 } else {
556 fm_set_msg('Nothing selected', 'alert');
557 }
558 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
559}
560
561// Rename
562if (isset($_GET['ren'], $_GET['to']) && !FM_READONLY) {
563 // old name
564 $old = $_GET['ren'];
565 $old = fm_clean_path($old);
566 $old = str_replace('/', '', $old);
567 // new name
568 $new = $_GET['to'];
569 $new = fm_clean_path($new);
570 $new = str_replace('/', '', $new);
571 // path
572 $path = FM_ROOT_PATH;
573 if (FM_PATH != '') {
574 $path .= '/' . FM_PATH;
575 }
576 // rename
577 if ($old != '' && $new != '') {
578 if (fm_rename($path . '/' . $old, $path . '/' . $new)) {
579 fm_set_msg(sprintf('Renamed from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)));
580 } else {
581 fm_set_msg(sprintf('Error while renaming from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)), 'error');
582 }
583 } else {
584 fm_set_msg('Names not set', 'error');
585 }
586 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
587}
588
589// Download
590if (isset($_GET['dl'])) {
591 $dl = $_GET['dl'];
592 $dl = fm_clean_path($dl);
593 $dl = str_replace('/', '', $dl);
594 $path = FM_ROOT_PATH;
595 if (FM_PATH != '') {
596 $path .= '/' . FM_PATH;
597 }
598 if ($dl != '' && is_file($path . '/' . $dl)) {
599 header('Content-Description: File Transfer');
600 header('Content-Type: application/octet-stream');
601 header('Content-Disposition: attachment; filename="' . basename($path . '/' . $dl) . '"');
602 header('Content-Transfer-Encoding: binary');
603 header('Connection: Keep-Alive');
604 header('Expires: 0');
605 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
606 header('Pragma: public');
607 header('Content-Length: ' . filesize($path . '/' . $dl));
608 ob_end_clean();
609 readfile($path . '/' . $dl);
610 exit;
611 } else {
612 fm_set_msg('File not found', 'error');
613 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
614 }
615}
616
617// Upload
618if (!empty($_FILES) && !FM_READONLY) {
619 $f = $_FILES;
620 $path = FM_ROOT_PATH;
621 $ds = DIRECTORY_SEPARATOR;
622 if (FM_PATH != '') {
623 $path .= '/' . FM_PATH;
624 }
625
626 $errors = 0;
627 $uploads = 0;
628 $total = count($f['file']['name']);
629 $allowed = (FM_EXTENSION) ? explode(',', FM_EXTENSION) : false;
630
631 $filename = $f['file']['name'];
632 $tmp_name = $f['file']['tmp_name'];
633 $ext = pathinfo($filename, PATHINFO_EXTENSION);
634 $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;
635
636 $targetPath = $path . $ds;
637 $fullPath = $path . '/' . $_REQUEST['fullpath'];
638 $folder = substr($fullPath, 0, strrpos($fullPath, "/"));
639
640 if (!is_dir($folder)) {
641 $old = umask(0);
642 mkdir($folder, 0777, true);
643 umask($old);
644 }
645
646 if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) {
647 if (move_uploaded_file($tmp_name, $fullPath)) {
648 die('Successfully uploaded');
649 } else {
650 die(sprintf('Error while uploading files. Uploaded files: %s', $uploads));
651 }
652 }
653 exit();
654}
655
656// Mass deleting
657if (isset($_POST['group'], $_POST['delete']) && !FM_READONLY) {
658 $path = FM_ROOT_PATH;
659 if (FM_PATH != '') {
660 $path .= '/' . FM_PATH;
661 }
662
663 $errors = 0;
664 $files = $_POST['file'];
665 if (is_array($files) && count($files)) {
666 foreach ($files as $f) {
667 if ($f != '') {
668 $new_path = $path . '/' . $f;
669 if (!fm_rdelete($new_path)) {
670 $errors++;
671 }
672 }
673 }
674 if ($errors == 0) {
675 fm_set_msg('Selected files and folder deleted');
676 } else {
677 fm_set_msg('Error while deleting items', 'error');
678 }
679 } else {
680 fm_set_msg('Nothing selected', 'alert');
681 }
682
683 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
684}
685
686// Pack files
687if (isset($_POST['group']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) {
688 $path = FM_ROOT_PATH;
689 $ext = 'zip';
690 if (FM_PATH != '') {
691 $path .= '/' . FM_PATH;
692 }
693
694 //set pack type
695 $ext = isset($_POST['tar']) ? 'tar' : 'zip';
696
697
698 if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
699 fm_set_msg('Operations with archives are not available', 'error');
700 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
701 }
702
703 $files = $_POST['file'];
704 if (!empty($files)) {
705 chdir($path);
706
707 if (count($files) == 1) {
708 $one_file = reset($files);
709 $one_file = basename($one_file);
710 $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext;
711 } else {
712 $zipname = 'archive_' . date('ymd_His') . '.'.$ext;
713 }
714
715 if($ext == 'zip') {
716 $zipper = new FM_Zipper();
717 $res = $zipper->create($zipname, $files);
718 } elseif ($ext == 'tar') {
719 $tar = new FM_Zipper_Tar();
720 $res = $tar->create($zipname, $files);
721 }
722
723 if ($res) {
724 fm_set_msg(sprintf('Archive <b>%s</b> created', fm_enc($zipname)));
725 } else {
726 fm_set_msg('Archive not created', 'error');
727 }
728 } else {
729 fm_set_msg('Nothing selected', 'alert');
730 }
731
732 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
733}
734
735// Unpack
736if (isset($_GET['unzip']) && !FM_READONLY) {
737 $unzip = $_GET['unzip'];
738 $unzip = fm_clean_path($unzip);
739 $unzip = str_replace('/', '', $unzip);
740 $isValid = false;
741
742 $path = FM_ROOT_PATH;
743 if (FM_PATH != '') {
744 $path .= '/' . FM_PATH;
745 }
746
747 if ($unzip != '' && is_file($path . '/' . $unzip)) {
748 $zip_path = $path . '/' . $unzip;
749 $ext = pathinfo($zip_path, PATHINFO_EXTENSION);
750 $isValid = true;
751 } else {
752 fm_set_msg('File not found', 'error');
753 }
754
755
756 if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
757 fm_set_msg('Operations with archives are not available', 'error');
758 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
759 }
760
761 if ($isValid) {
762 //to folder
763 $tofolder = '';
764 if (isset($_GET['tofolder'])) {
765 $tofolder = pathinfo($zip_path, PATHINFO_FILENAME);
766 if (fm_mkdir($path . '/' . $tofolder, true)) {
767 $path .= '/' . $tofolder;
768 }
769 }
770
771 if($ext == "zip") {
772 $zipper = new FM_Zipper();
773 $res = $zipper->unzip($zip_path, $path);
774 } elseif ($ext == "tar") {
775 $gzipper = new PharData($zip_path);
776 $res = $gzipper->extractTo($path);
777 }
778
779 if ($res) {
780 fm_set_msg('Archive unpacked');
781 } else {
782 fm_set_msg('Archive not unpacked', 'error');
783 }
784
785 } else {
786 fm_set_msg('File not found', 'error');
787 }
788 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
789}
790
791// Change Perms (not for Windows)
792if (isset($_POST['chmod']) && !FM_READONLY && !FM_IS_WIN) {
793 $path = FM_ROOT_PATH;
794 if (FM_PATH != '') {
795 $path .= '/' . FM_PATH;
796 }
797
798 $file = $_POST['chmod'];
799 $file = fm_clean_path($file);
800 $file = str_replace('/', '', $file);
801 if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
802 fm_set_msg('File not found', 'error');
803 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
804 }
805
806 $mode = 0;
807 if (!empty($_POST['ur'])) {
808 $mode |= 0400;
809 }
810 if (!empty($_POST['uw'])) {
811 $mode |= 0200;
812 }
813 if (!empty($_POST['ux'])) {
814 $mode |= 0100;
815 }
816 if (!empty($_POST['gr'])) {
817 $mode |= 0040;
818 }
819 if (!empty($_POST['gw'])) {
820 $mode |= 0020;
821 }
822 if (!empty($_POST['gx'])) {
823 $mode |= 0010;
824 }
825 if (!empty($_POST['or'])) {
826 $mode |= 0004;
827 }
828 if (!empty($_POST['ow'])) {
829 $mode |= 0002;
830 }
831 if (!empty($_POST['ox'])) {
832 $mode |= 0001;
833 }
834
835 if (@chmod($path . '/' . $file, $mode)) {
836 fm_set_msg('Permissions changed');
837 } else {
838 fm_set_msg('Permissions not changed', 'error');
839 }
840
841 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
842}
843
844/*************************** /ACTIONS ***************************/
845
846// get current path
847$path = FM_ROOT_PATH;
848if (FM_PATH != '') {
849 $path .= '/' . FM_PATH;
850}
851
852// check path
853if (!is_dir($path)) {
854 fm_redirect(FM_SELF_URL . '?p=');
855}
856
857// get parent folder
858$parent = fm_get_parent_path(FM_PATH);
859
860$objects = is_readable($path) ? scandir($path) : array();
861$folders = array();
862$files = array();
863if (is_array($objects)) {
864 foreach ($objects as $file) {
865 if ($file == '.' || $file == '..' && in_array($file, $GLOBALS['exclude_items'])) {
866 continue;
867 }
868 if (!FM_SHOW_HIDDEN && substr($file, 0, 1) === '.') {
869 continue;
870 }
871 $new_path = $path . '/' . $file;
872 if (@is_file($new_path) && !in_array($file, $GLOBALS['exclude_items'])) {
873 $files[] = $file;
874 } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && !in_array($file, $GLOBALS['exclude_items'])) {
875 $folders[] = $file;
876 }
877 }
878}
879
880if (!empty($files)) {
881 natcasesort($files);
882}
883if (!empty($folders)) {
884 natcasesort($folders);
885}
886
887// upload form
888if (isset($_GET['upload']) && !FM_READONLY) {
889 fm_show_header(); // HEADER
890 fm_show_nav_path(FM_PATH); // current path
891 ?>
892
893 <link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.css" rel="stylesheet">
894 <div class="path">
895
896 <div class="card mb-2 fm-upload-wrapper">
897 <div class="card-header">
898 <ul class="nav nav-tabs card-header-tabs">
899 <li class="nav-item">
900 <a class="nav-link active" href="#fileUploader" data-target="#fileUploader"><i class="fa fa-arrow-circle-o-up"></i> <?php echo lng('UploadingFiles') ?></a>
901 </li>
902 <li class="nav-item">
903 <a class="nav-link" href="#urlUploader" class="js-url-upload" data-target="#urlUploader"><i class="fa fa-link"></i> Upload from URL</a>
904 </li>
905 </ul>
906 </div>
907 <div class="card-body">
908 <p class="card-text">
909 <a href="?p=<?php echo FM_PATH ?>" class="float-right"><i class="fa fa-chevron-circle-left go-back"></i> <?php echo lng('Back')?></a>
910 <?php echo lng('DestinationFolder') ?>: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?>
911 </p>
912
913 <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]) . '?p=' . fm_enc(FM_PATH) ?>" class="dropzone card-tabs-container" id="fileUploader" enctype="multipart/form-data">
914 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
915 <input type="hidden" name="fullpath" id="fullpath" value="<?php echo fm_enc(FM_PATH) ?>">
916 <div class="fallback">
917 <input name="file" type="file" multiple/>
918 </div>
919 </form>
920
921 <div class="upload-url-wrapper card-tabs-container hidden" id="urlUploader">
922 <form id="js-form-url-upload" class="form-inline" onsubmit="return upload_from_url(this);" method="POST" action="">
923 <input type="hidden" name="type" value="upload" aria-label="hidden" aria-hidden="true">
924 <input type="url" placeholder="URL" name="uploadurl" required class="form-control" style="width: 80%">
925 <button type="submit" class="btn btn-primary ml-3"><?php echo lng('Upload') ?></button>
926 <div class="lds-facebook"><div></div><div></div><div></div></div>
927 </form>
928 <div id="js-url-upload__list" class="col-9 mt-3"></div>
929 </div>
930 </div>
931 </div>
932 </div>
933 <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.js"></script>
934 <script>
935 Dropzone.options.fileUploader = {
936 timeout: 120000,
937 init: function () {
938 this.on("sending", function (file, xhr, formData) {
939 let _path = (file.fullPath) ? file.fullPath : file.name;
940 document.getElementById("fullpath").value = _path;
941 xhr.ontimeout = (() => {
942 alert('Error: Server Timeout');
943 });
944 }).on("success", function (res) {
945 console.log('Upload Status >> ', res.status);
946 }).on("error", function(file, response) {
947 alert(response);
948 });
949 }
950 }
951 </script>
952 <?php
953 fm_show_footer();
954 exit;
955}
956
957// copy form POST
958if (isset($_POST['copy']) && !FM_READONLY) {
959 $copy_files = $_POST['file'];
960 if (!is_array($copy_files) || empty($copy_files)) {
961 fm_set_msg('Nothing selected', 'alert');
962 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
963 }
964
965 fm_show_header(); // HEADER
966 fm_show_nav_path(FM_PATH); // current path
967 ?>
968 <div class="path">
969 <div class="card">
970 <div class="card-header">
971 <h6><?php echo lng('Copying') ?></h6>
972 </div>
973 <div class="card-body">
974 <form action="" method="post">
975 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
976 <input type="hidden" name="finish" value="1">
977 <?php
978 foreach ($copy_files as $cf) {
979 echo '<input type="hidden" name="file[]" value="' . fm_enc($cf) . '">' . PHP_EOL;
980 }
981 ?>
982 <p class="break-word"><?php echo lng('Files') ?>: <b><?php echo implode('</b>, <b>', $copy_files) ?></b></p>
983 <p class="break-word"><?php echo lng('SourceFolder') ?>: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?><br>
984 <label for="inp_copy_to"><?php echo lng('DestinationFolder') ?>:</label>
985 <?php echo FM_ROOT_PATH ?>/<input type="text" name="copy_to" id="inp_copy_to" value="<?php echo fm_enc(FM_PATH) ?>">
986 </p>
987 <p class="custom-checkbox custom-control"><input type="checkbox" name="move" value="1" id="js-move-files" class="custom-control-input"><label for="js-move-files" class="custom-control-label" style="vertical-align: sub"> <?php echo lng('Move') ?></label></p>
988 <p>
989 <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo lng('Copy') ?></button>
990 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>" class="btn btn-outline-primary"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></a></b>
991 </p>
992 </form>
993 </div>
994 </div>
995 </div>
996 <?php
997 fm_show_footer();
998 exit;
999}
1000
1001// copy form
1002if (isset($_GET['copy']) && !isset($_GET['finish']) && !FM_READONLY) {
1003 $copy = $_GET['copy'];
1004 $copy = fm_clean_path($copy);
1005 if ($copy == '' || !file_exists(FM_ROOT_PATH . '/' . $copy)) {
1006 fm_set_msg('File not found', 'error');
1007 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1008 }
1009
1010 fm_show_header(); // HEADER
1011 fm_show_nav_path(FM_PATH); // current path
1012 ?>
1013 <div class="path">
1014 <p><b>Copying</b></p>
1015 <p class="break-word">
1016 Source path: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . $copy)) ?><br>
1017 Destination folder: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?>
1018 </p>
1019 <p>
1020 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&copy=<?php echo urlencode($copy) ?>&finish=1"><i class="fa fa-check-circle"></i> Copy</a></b>
1021 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&copy=<?php echo urlencode($copy) ?>&finish=1&move=1"><i class="fa fa-check-circle"></i> Move</a></b>
1022 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="fa fa-times-circle"></i> Cancel</a></b>
1023 </p>
1024 <p><i>Select folder</i></p>
1025 <ul class="folders break-word">
1026 <?php
1027 if ($parent !== false) {
1028 ?>
1029 <li><a href="?p=<?php echo urlencode($parent) ?>&copy=<?php echo urlencode($copy) ?>"><i class="fa fa-chevron-circle-left"></i> ..</a></li>
1030 <?php
1031 }
1032 foreach ($folders as $f) {
1033 ?>
1034 <li>
1035 <a href="?p=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>&copy=<?php echo urlencode($copy) ?>"><i class="fa fa-folder-o"></i> <?php echo fm_convert_win($f) ?></a></li>
1036 <?php
1037 }
1038 ?>
1039 </ul>
1040 </div>
1041 <?php
1042 fm_show_footer();
1043 exit;
1044}
1045
1046if (isset($_GET['settings']) && !FM_READONLY) {
1047 fm_show_header(); // HEADER
1048 fm_show_nav_path(FM_PATH); // current path
1049 global $cfg, $lang, $lang_list;
1050 ?>
1051
1052 <div class="col-md-8 offset-md-2 pt-3">
1053 <div class="card mb-2">
1054 <h6 class="card-header">
1055 <i class="fa fa-cog"></i> <?php echo lng('Settings') ?>
1056 <a href="?p=<?php echo FM_PATH ?>" class="float-right"><i class="fa fa-window-close"></i> <?php echo lng('Cancel')?></a>
1057 </h6>
1058 <div class="card-body">
1059 <form id="js-settings-form" action="" method="post" data-type="ajax" onsubmit="return save_settings(this)">
1060 <input type="hidden" name="type" value="settings" aria-label="hidden" aria-hidden="true">
1061 <div class="form-group row">
1062 <label for="js-language" class="col-sm-3 col-form-label"><?php echo lng('Language') ?></label>
1063 <div class="col-sm-5">
1064 <select class="form-control" id="js-language" name="js-language">
1065 <?php
1066 function getSelected($l) {
1067 global $lang;
1068 return ($lang == $l) ? 'selected' : '';
1069 }
1070 foreach ($lang_list as $k => $v) {
1071 echo "<option value='$k' ".getSelected($k).">$v</option>";
1072 }
1073 ?>
1074 </select>
1075 </div>
1076 </div>
1077 <?php
1078 //get ON/OFF and active class
1079 function getChecked($conf, $val, $txt) {
1080 if($conf== 1 && $val ==1) {
1081 return $txt;
1082 } else if($conf == '' && $val == '') {
1083 return $txt;
1084 } else {
1085 return '';
1086 }
1087 }
1088 ?>
1089 <div class="form-group row">
1090 <label for="js-err-rpt-1" class="col-sm-3 col-form-label"><?php echo lng('ErrorReporting') ?></label>
1091 <div class="col-sm-9">
1092 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1093 <label class="btn btn-secondary <?php echo getChecked($report_errors, 1, 'active') ?>">
1094 <input type="radio" name="js-error-report" id="js-err-rpt-1" autocomplete="off" value="true" <?php echo getChecked($report_errors, 1, 'checked') ?> > ON
1095 </label>
1096 <label class="btn btn-secondary <?php echo getChecked($report_errors, '', 'active') ?>">
1097 <input type="radio" name="js-error-report" id="js-err-rpt-0" autocomplete="off" value="false" <?php echo getChecked($report_errors, '', 'checked') ?> > OFF
1098 </label>
1099 </div>
1100 </div>
1101 </div>
1102
1103 <div class="form-group row">
1104 <label for="js-hdn-1" class="col-sm-3 col-form-label"><?php echo lng('ShowHiddenFiles') ?></label>
1105 <div class="col-sm-9">
1106 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1107 <label class="btn btn-secondary <?php echo getChecked($show_hidden_files, 1, 'active') ?>">
1108 <input type="radio" name="js-show-hidden" id="js-hdn-1" autocomplete="off" value="true" <?php echo getChecked($show_hidden_files, 1, 'checked') ?> > ON
1109 </label>
1110 <label class="btn btn-secondary <?php echo getChecked($show_hidden_files, '', 'active') ?>">
1111 <input type="radio" name="js-show-hidden" id="js-hdn-0" autocomplete="off" value="false" <?php echo getChecked($show_hidden_files, '', 'checked') ?> > OFF
1112 </label>
1113 </div>
1114 </div>
1115 </div>
1116
1117 <div class="form-group row">
1118 <div class="col-sm-10">
1119 <button type="submit" class="btn btn-success"> <i class="fa fa-check-circle"></i> <?php echo lng('Save'); ?></button>
1120 </div>
1121 </div>
1122
1123 </form>
1124 </div>
1125 </div>
1126 </div>
1127 <?php
1128 fm_show_footer();
1129 exit;
1130}
1131
1132if (isset($_GET['help'])) {
1133 fm_show_header(); // HEADER
1134 fm_show_nav_path(FM_PATH); // current path
1135 global $cfg, $lang;
1136 ?>
1137
1138 <div class="col-md-8 offset-md-2 pt-3">
1139 <div class="card mb-2">
1140 <h6 class="card-header">
1141 <i class="fa fa-exclamation-circle"></i> <?php echo lng('Help') ?>
1142 <a href="?p=<?php echo FM_PATH ?>" class="float-right"><i class="fa fa-window-close"></i> <?php echo lng('Cancel')?></a>
1143 </h6>
1144 <div class="card-body">
1145 <div class="row">
1146 <div class="col-xs-12 col-sm-6">
1147 <p><h3><a href="https://github.com/prasathmani/tinyfilemanager" target="_blank" class="app-v-title"> Tiny File Manager <?php echo VERSION; ?></a></h3></p>
1148 <p>Author: Prasath Mani</p>
1149 <p>Mail Us: <a href="mailto:ccpprogrammers@gmail.com">ccpprogrammers[at]gmail.com</a> </p>
1150 </div>
1151 <div class="col-xs-12 col-sm-6">
1152 <div class="card">
1153 <ul class="list-group list-group-flush">
1154 <li class="list-group-item"><a href="https://tinyfilemanager.github.io/" target="_blank"><i class="fa fa-question-circle"></i> Help Documents</a> </li>
1155 <li class="list-group-item"><a href="https://github.com/prasathmani/tinyfilemanager/issues" target="_blank"><i class="fa fa-bug"></i> Report Issue</a></li>
1156 <li class="list-group-item"><a href="javascript:latest_release_info('<?php echo VERSION; ?>');" target="_blank"><i class="fa fa-link"></i> Check Latest Version</a></li>
1157 <?php if(!FM_READONLY) { ?>
1158 <li class="list-group-item"><a href="javascript:show_new_pwd();" target="_blank"><i class="fa fa-lock"></i> Generate new password hash</a></li>
1159 <?php } ?>
1160 </ul>
1161 </div>
1162 </div>
1163 </div>
1164 <div class="row js-new-pwd hidden mt-2">
1165 <div class="col-12">
1166 <form class="form-inline" onsubmit="return new_password_hash(this)" method="POST" action="">
1167 <input type="hidden" name="type" value="pwdhash" aria-label="hidden" aria-hidden="true">
1168 <div class="form-group mb-2">
1169 <label for="staticEmail2">Generate new password hash</label>
1170 </div>
1171 <div class="form-group mx-sm-3 mb-2">
1172 <label for="inputPassword2" class="sr-only">Password</label>
1173 <input type="text" class="form-control btn-sm" id="inputPassword2" name="inputPassword2" placeholder="Password" required>
1174 </div>
1175 <button type="submit" class="btn btn-success btn-sm mb-2">Generate</button>
1176 </form>
1177 <textarea class="form-control" rows="2" readonly id="js-pwd-result"></textarea>
1178 </div>
1179 </div>
1180 </div>
1181 </div>
1182 </div>
1183 <?php
1184 fm_show_footer();
1185 exit;
1186}
1187
1188// file viewer
1189if (isset($_GET['view'])) {
1190 $file = $_GET['view'];
1191 $file = fm_clean_path($file);
1192 $file = str_replace('/', '', $file);
1193 if ($file == '' || !is_file($path . '/' . $file)) {
1194 fm_set_msg('File not found', 'error');
1195 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1196 }
1197
1198 fm_show_header(); // HEADER
1199 fm_show_nav_path(FM_PATH); // current path
1200
1201 $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
1202 $file_path = $path . '/' . $file;
1203
1204 $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
1205 $mime_type = fm_get_mime_type($file_path);
1206 $filesize = filesize($file_path);
1207
1208 $is_zip = false;
1209 $is_gzip = false;
1210 $is_image = false;
1211 $is_audio = false;
1212 $is_video = false;
1213 $is_text = false;
1214 $is_onlineViewer = false;
1215
1216 $view_title = 'File';
1217 $filenames = false; // for zip
1218 $content = ''; // for text
1219
1220 if($GLOBALS['online_viewer'] && in_array($ext, fm_get_onlineViewer_exts())){
1221 $is_onlineViewer = true;
1222 }
1223 elseif ($ext == 'zip' || $ext == 'tar') {
1224 $is_zip = true;
1225 $view_title = 'Archive';
1226 $filenames = fm_get_zif_info($file_path, $ext);
1227 } elseif (in_array($ext, fm_get_image_exts())) {
1228 $is_image = true;
1229 $view_title = 'Image';
1230 } elseif (in_array($ext, fm_get_audio_exts())) {
1231 $is_audio = true;
1232 $view_title = 'Audio';
1233 } elseif (in_array($ext, fm_get_video_exts())) {
1234 $is_video = true;
1235 $view_title = 'Video';
1236 } elseif (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) {
1237 $is_text = true;
1238 $content = file_get_contents($file_path);
1239 }
1240
1241 ?>
1242 <div class="row">
1243 <div class="col-12">
1244 <p class="break-word"><b><?php echo $view_title ?> "<?php echo fm_enc(fm_convert_win($file)) ?>"</b></p>
1245 <p class="break-word">
1246 Full path: <?php echo fm_enc(fm_convert_win($file_path)) ?><br>
1247 File
1248 size: <?php echo fm_get_filesize($filesize) ?><?php if ($filesize >= 1000): ?> (<?php echo sprintf('%s bytes', $filesize) ?>)<?php endif; ?>
1249 <br>
1250 MIME-type: <?php echo $mime_type ?><br>
1251 <?php
1252 // ZIP info
1253 if (($is_zip || $is_gzip) && $filenames !== false) {
1254 $total_files = 0;
1255 $total_comp = 0;
1256 $total_uncomp = 0;
1257 foreach ($filenames as $fn) {
1258 if (!$fn['folder']) {
1259 $total_files++;
1260 }
1261 $total_comp += $fn['compressed_size'];
1262 $total_uncomp += $fn['filesize'];
1263 }
1264 ?>
1265 Files in archive: <?php echo $total_files ?><br>
1266 Total size: <?php echo fm_get_filesize($total_uncomp) ?><br>
1267 Size in archive: <?php echo fm_get_filesize($total_comp) ?><br>
1268 Compression: <?php echo round(($total_comp / $total_uncomp) * 100) ?>%<br>
1269 <?php
1270 }
1271 // Image info
1272 if ($is_image) {
1273 $image_size = getimagesize($file_path);
1274 echo 'Image sizes: ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '<br>';
1275 }
1276 // Text info
1277 if ($is_text) {
1278 $is_utf8 = fm_is_utf8($content);
1279 if (function_exists('iconv')) {
1280 if (!$is_utf8) {
1281 $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content);
1282 }
1283 }
1284 echo 'Charset: ' . ($is_utf8 ? 'utf-8' : '8 bit') . '<br>';
1285 }
1286 ?>
1287 </p>
1288 <p>
1289 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&dl=<?php echo urlencode($file) ?>"><i class="fa fa-cloud-download"></i> <?php echo lng('Download') ?></a></b>
1290 <b><a href="<?php echo fm_enc($file_url) ?>" target="_blank"><i class="fa fa-external-link-square"></i> <?php echo lng('Open') ?></a></b>
1291
1292 <?php
1293 // ZIP actions
1294 if (!FM_READONLY && ($is_zip || $is_gzip) && $filenames !== false) {
1295 $zip_name = pathinfo($file_path, PATHINFO_FILENAME);
1296 ?>
1297 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&unzip=<?php echo urlencode($file) ?>"><i class="fa fa-check-circle"></i> <?php echo lng('UnZip') ?></a></b>
1298 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>&unzip=<?php echo urlencode($file) ?>&tofolder=1" title="UnZip to <?php echo fm_enc($zip_name) ?>"><i class="fa fa-check-circle"></i>
1299 <?php echo lng('UnZipToFolder') ?></a></b>
1300 <?php
1301 }
1302 if ($is_text && !FM_READONLY) {
1303 ?>
1304 <b><a href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&edit=<?php echo urlencode($file) ?>" class="edit-file"><i class="fa fa-pencil-square"></i> <?php echo lng('Edit') ?></a></b>
1305 <b><a href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&edit=<?php echo urlencode($file) ?>&env=ace" class="edit-file"><i class="fa fa-pencil-square-o"></i> <?php echo lng('AdvancedEditor') ?></a></b>
1306 <?php } ?>
1307 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="fa fa-chevron-circle-left go-back"></i> <?php echo lng('Back') ?></a></b>
1308 </p>
1309 <?php
1310 if($is_onlineViewer) {
1311 // Google docs viewer
1312 echo '<iframe src="https://docs.google.com/viewer?embedded=true&hl=en&url=' . fm_enc($file_url) . '" frameborder="no" style="width:100%;min-height:460px"></iframe>';
1313 } elseif ($is_zip) {
1314 // ZIP content
1315 if ($filenames !== false) {
1316 echo '<code class="maxheight">';
1317 foreach ($filenames as $fn) {
1318 if ($fn['folder']) {
1319 echo '<b>' . fm_enc($fn['name']) . '</b><br>';
1320 } else {
1321 echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')<br>';
1322 }
1323 }
1324 echo '</code>';
1325 } else {
1326 echo '<p>Error while fetching archive info</p>';
1327 }
1328 } elseif ($is_image) {
1329 // Image content
1330 if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico'))) {
1331 echo '<p><img src="' . fm_enc($file_url) . '" alt="" class="preview-img"></p>';
1332 }
1333 } elseif ($is_audio) {
1334 // Audio content
1335 echo '<p><audio src="' . fm_enc($file_url) . '" controls preload="metadata"></audio></p>';
1336 } elseif ($is_video) {
1337 // Video content
1338 echo '<div class="preview-video"><video src="' . fm_enc($file_url) . '" width="640" height="360" controls preload="metadata"></video></div>';
1339 } elseif ($is_text) {
1340 if (FM_USE_HIGHLIGHTJS) {
1341 // highlight
1342 $hljs_classes = array(
1343 'shtml' => 'xml',
1344 'htaccess' => 'apache',
1345 'phtml' => 'php',
1346 'lock' => 'json',
1347 'svg' => 'xml',
1348 );
1349 $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext;
1350 if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) {
1351 $hljs_class = 'nohighlight';
1352 }
1353 $content = '<pre class="with-hljs"><code class="' . $hljs_class . '">' . fm_enc($content) . '</code></pre>';
1354 } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) {
1355 // php highlight
1356 $content = highlight_string($content, true);
1357 } else {
1358 $content = '<pre>' . fm_enc($content) . '</pre>';
1359 }
1360 echo $content;
1361 }
1362 ?>
1363 </div>
1364 </div>
1365 <?php
1366 fm_show_footer();
1367 exit;
1368}
1369
1370// file editor
1371if (isset($_GET['edit'])) {
1372 $file = $_GET['edit'];
1373 $file = fm_clean_path($file);
1374 $file = str_replace('/', '', $file);
1375 if ($file == '' || !is_file($path . '/' . $file)) {
1376 fm_set_msg('File not found', 'error');
1377 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1378 }
1379 header('X-XSS-Protection:0');
1380 fm_show_header(); // HEADER
1381 fm_show_nav_path(FM_PATH); // current path
1382
1383 $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
1384 $file_path = $path . '/' . $file;
1385
1386 // normal editer
1387 $isNormalEditor = true;
1388 if (isset($_GET['env'])) {
1389 if ($_GET['env'] == "ace") {
1390 $isNormalEditor = false;
1391 }
1392 }
1393
1394 // Save File
1395 if (isset($_POST['savedata'])) {
1396 $writedata = $_POST['savedata'];
1397 $fd = fopen($file_path, "w");
1398 @fwrite($fd, $writedata);
1399 fclose($fd);
1400 fm_set_msg('File Saved Successfully', 'alert');
1401 }
1402
1403 $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
1404 $mime_type = fm_get_mime_type($file_path);
1405 $filesize = filesize($file_path);
1406 $is_text = false;
1407 $content = ''; // for text
1408
1409 if (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) {
1410 $is_text = true;
1411 $content = file_get_contents($file_path);
1412 }
1413
1414 ?>
1415 <div class="path">
1416 <div class="row">
1417 <div class="col-xs-12 col-sm-5 col-lg-6 pt-1">
1418 <div class="btn-toolbar" role="toolbar">
1419 <?php if (!$isNormalEditor) { ?>
1420 <div class="btn-group js-ace-toolbar">
1421 <button data-cmd="none" data-option="fullscreen" class="btn btn-sm btn-outline-secondary" id="js-ace-fullscreen" title="Fullscreen"><i class="fa fa-expand" title="Fullscreen"></i></button>
1422 <button data-cmd="find" class="btn btn-sm btn-outline-secondary" id="js-ace-search" title="Search"><i class="fa fa-search" title="Search"></i></button>
1423 <button data-cmd="undo" class="btn btn-sm btn-outline-secondary" id="js-ace-undo" title="Undo"><i class="fa fa-undo" title="Undo"></i></button>
1424 <button data-cmd="redo" class="btn btn-sm btn-outline-secondary" id="js-ace-redo" title="Redo"><i class="fa fa-repeat" title="Redo"></i></button>
1425 <button data-cmd="none" data-option="wrap" class="btn btn-sm btn-outline-secondary" id="js-ace-wordWrap" title="Word Wrap"><i class="fa fa-text-width" title="Word Wrap"></i></button>
1426 <button data-cmd="none" data-option="help" class="btn btn-sm btn-outline-secondary" id="js-ace-goLine" title="Help"><i class="fa fa-question" title="Help"></i></button>
1427 <select id="js-ace-mode" data-type="mode" title="Select Document Type" class="btn-outline-secondary border-left-0 d-none d-md-block"><option>-- Select Mode --</option></select>
1428 <select id="js-ace-theme" data-type="theme" title="Select Theme" class="btn-outline-secondary border-left-0 d-none d-lg-block"><option>-- Select Theme --</option></select>
1429 </div>
1430 <?php } ?>
1431 </div>
1432 </div>
1433 <div class="edit-file-actions col-xs-12 col-sm-7 col-lg-6 text-right pt-1">
1434 <a title="Back" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&view=<?php echo urlencode($file) ?>"><i class="fa fa-reply-all"></i> <?php echo lng('Back') ?></a>
1435 <a title="Backup" class="btn btn-sm btn-outline-primary" href="javascript:backup('<?php echo urlencode($path) ?>','<?php echo urlencode($file) ?>')"><i class="fa fa-database"></i> <?php echo lng('BackUp') ?></a>
1436 <?php if ($is_text) { ?>
1437 <?php if ($isNormalEditor) { ?>
1438 <a title="Advanced" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&edit=<?php echo urlencode($file) ?>&env=ace"><i class="fa fa-pencil-square-o"></i> <?php echo lng('AdvancedEditor') ?></a>
1439 <button type="button" class="btn btn-sm btn-outline-primary name="Save" data-url="<?php echo fm_enc($file_url) ?>" onclick="edit_save(this,'nrl')"><i class="fa fa-floppy-o"></i> Save
1440 </button>
1441 <?php } else { ?>
1442 <a title="Plain Editor" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&edit=<?php echo urlencode($file) ?>"><i class="fa fa-text-height"></i> <?php echo lng('NormalEditor') ?></a>
1443 <button type="button" class="btn btn-sm btn-outline-primary" name="Save" data-url="<?php echo fm_enc($file_url) ?>" onclick="edit_save(this,'ace')"><i class="fa fa-floppy-o"></i> <?php echo lng('Save') ?>
1444 </button>
1445 <?php } ?>
1446 <?php } ?>
1447 </div>
1448 </div>
1449 <?php
1450 if ($is_text && $isNormalEditor) {
1451 echo '<textarea class="mt-2" id="normal-editor" rows="33" cols="120" style="width: 99.5%;">' . htmlspecialchars($content) . '</textarea>';
1452 } elseif ($is_text) {
1453 echo '<div id="editor" contenteditable="true">' . htmlspecialchars($content) . '</div>';
1454 } else {
1455 fm_set_msg('FILE EXTENSION HAS NOT SUPPORTED', 'error');
1456 }
1457 ?>
1458 </div>
1459 <?php
1460 fm_show_footer();
1461 exit;
1462}
1463
1464// chmod (not for Windows)
1465if (isset($_GET['chmod']) && !FM_READONLY && !FM_IS_WIN) {
1466 $file = $_GET['chmod'];
1467 $file = fm_clean_path($file);
1468 $file = str_replace('/', '', $file);
1469 if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
1470 fm_set_msg('File not found', 'error');
1471 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1472 }
1473
1474 fm_show_header(); // HEADER
1475 fm_show_nav_path(FM_PATH); // current path
1476
1477 $file_url = FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file;
1478 $file_path = $path . '/' . $file;
1479
1480 $mode = fileperms($path . '/' . $file);
1481
1482 ?>
1483 <div class="path">
1484 <div class="card mb-2">
1485 <h6 class="card-header">
1486 <?php echo lng('ChangePermissions') ?>
1487 </h6>
1488 <div class="card-body">
1489 <p class="card-text">
1490 Full path: <?php echo $file_path ?><br>
1491 </p>
1492 <form action="" method="post">
1493 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1494 <input type="hidden" name="chmod" value="<?php echo fm_enc($file) ?>">
1495
1496 <table class="table compact-table">
1497 <tr>
1498 <td></td>
1499 <td><b><?php echo lng('Owner') ?></b></td>
1500 <td><b><?php echo lng('Group') ?></b></td>
1501 <td><b><?php echo lng('Other') ?></b></td>
1502 </tr>
1503 <tr>
1504 <td style="text-align: right"><b><?php echo lng('Read') ?></b></td>
1505 <td><label><input type="checkbox" name="ur" value="1"<?php echo ($mode & 00400) ? ' checked' : '' ?>></label></td>
1506 <td><label><input type="checkbox" name="gr" value="1"<?php echo ($mode & 00040) ? ' checked' : '' ?>></label></td>
1507 <td><label><input type="checkbox" name="or" value="1"<?php echo ($mode & 00004) ? ' checked' : '' ?>></label></td>
1508 </tr>
1509 <tr>
1510 <td style="text-align: right"><b><?php echo lng('Write') ?></b></td>
1511 <td><label><input type="checkbox" name="uw" value="1"<?php echo ($mode & 00200) ? ' checked' : '' ?>></label></td>
1512 <td><label><input type="checkbox" name="gw" value="1"<?php echo ($mode & 00020) ? ' checked' : '' ?>></label></td>
1513 <td><label><input type="checkbox" name="ow" value="1"<?php echo ($mode & 00002) ? ' checked' : '' ?>></label></td>
1514 </tr>
1515 <tr>
1516 <td style="text-align: right"><b><?php echo lng('Execute') ?></b></td>
1517 <td><label><input type="checkbox" name="ux" value="1"<?php echo ($mode & 00100) ? ' checked' : '' ?>></label></td>
1518 <td><label><input type="checkbox" name="gx" value="1"<?php echo ($mode & 00010) ? ' checked' : '' ?>></label></td>
1519 <td><label><input type="checkbox" name="ox" value="1"<?php echo ($mode & 00001) ? ' checked' : '' ?>></label></td>
1520 </tr>
1521 </table>
1522
1523 <p>
1524 <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo lng('Change') ?></button>
1525 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>" class="btn btn-outline-primary"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></a></b>
1526 </p>
1527 </form>
1528 </div>
1529 </div>
1530 </div>
1531 <?php
1532 fm_show_footer();
1533 exit;
1534}
1535
1536//--- FILEMANAGER MAIN
1537fm_show_header(); // HEADER
1538fm_show_nav_path(FM_PATH); // current path
1539
1540// messages
1541fm_show_message();
1542
1543$num_files = count($files);
1544$num_folders = count($folders);
1545$all_files_size = 0;
1546?>
1547<form action="" method="post" class="pt-3">
1548 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1549 <input type="hidden" name="group" value="1">
1550 <div class="table-responsive">
1551 <table class="table table-bordered table-hover table-sm bg-white" id="main-table">
1552 <thead class="thead-white">
1553 <tr>
1554 <?php if (!FM_READONLY): ?>
1555 <th style="width:3%" class="custom-checkbox-header">
1556 <div class="custom-control custom-checkbox">
1557 <input type="checkbox" class="custom-control-input" id="js-select-all-items" onclick="checkbox_toggle()">
1558 <label class="custom-control-label" for="js-select-all-items"></label>
1559 </div>
1560 </th><?php endif; ?>
1561 <th><?php echo lng('Name') ?></th>
1562 <th><?php echo lng('Size') ?></th>
1563 <th><?php echo lng('Modified') ?></th>
1564 <?php if (!FM_IS_WIN): ?>
1565 <th><?php echo lng('Perms') ?></th>
1566 <th><?php echo lng('Owner') ?></th><?php endif; ?>
1567 <th><?php echo lng('Actions') ?></th>
1568 </tr>
1569 </thead>
1570 <?php
1571 // link to parent folder
1572 if ($parent !== false) {
1573 ?>
1574 <tr><?php if (!FM_READONLY): ?>
1575 <td class="nosort"></td><?php endif; ?>
1576 <td class="border-0"><a href="?p=<?php echo urlencode($parent) ?>"><i class="fa fa-chevron-circle-left go-back"></i> ..</a></td>
1577 <td class="border-0"></td>
1578 <td class="border-0"></td>
1579 <td class="border-0"></td>
1580 <?php if (!FM_IS_WIN) { ?>
1581 <td class="border-0"></td>
1582 <td class="border-0"></td>
1583 <?php } ?>
1584 </tr>
1585 <?php
1586 }
1587 $ii = 3399;
1588 foreach ($folders as $f) {
1589 $is_link = is_link($path . '/' . $f);
1590 $img = $is_link ? 'icon-link_folder' : 'fa fa-folder-o';
1591 $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
1592 $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
1593 if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
1594 $owner = posix_getpwuid(fileowner($path . '/' . $f));
1595 $group = posix_getgrgid(filegroup($path . '/' . $f));
1596 } else {
1597 $owner = array('name' => '?');
1598 $group = array('name' => '?');
1599 }
1600 ?>
1601 <tr>
1602 <?php if (!FM_READONLY): ?>
1603 <td class="custom-checkbox-td">
1604 <div class="custom-control custom-checkbox">
1605 <input type="checkbox" class="custom-control-input" id="<?php echo $ii ?>" name="file[]" value="<?php echo fm_enc($f) ?>">
1606 <label class="custom-control-label" for="<?php echo $ii ?>"></label>
1607 </div>
1608 </td><?php endif; ?>
1609 <td>
1610 <div class="filename"><a href="?p=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="<?php echo $img ?>"></i> <?php echo fm_convert_win($f) ?>
1611 </a><?php echo($is_link ? ' → <i>' . readlink($path . '/' . $f) . '</i>' : '') ?></div>
1612 </td>
1613 <td><?php echo lng('Folder') ?></td>
1614 <td><?php echo $modif ?></td>
1615 <?php if (!FM_IS_WIN): ?>
1616 <td><?php if (!FM_READONLY): ?><a title="Change Permissions" href="?p=<?php echo urlencode(FM_PATH) ?>&chmod=<?php echo urlencode($f) ?>"><?php echo $perms ?></a><?php else: ?><?php echo $perms ?><?php endif; ?>
1617 </td>
1618 <td><?php echo $owner['name'] . ':' . $group['name'] ?></td>
1619 <?php endif; ?>
1620 <td class="inline-actions"><?php if (!FM_READONLY): ?>
1621 <a title="<?php echo lng('Delete')?>" href="?p=<?php echo urlencode(FM_PATH) ?>&del=<?php echo urlencode($f) ?>" onclick="return confirm('Delete folder?');"><i class="fa fa-trash-o" aria-hidden="true"></i></a>
1622 <a title="<?php echo lng('Rename')?>" href="#" onclick="rename('<?php echo fm_enc(FM_PATH) ?>', '<?php echo fm_enc(addslashes($f)) ?>');return false;"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a>
1623 <a title="<?php echo lng('CopyTo')?>..." href="?p=&copy=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="fa fa-files-o" aria-hidden="true"></i></a>
1624 <?php endif; ?>
1625 <a title="<?php echo lng('DirectLink')?>" href="<?php echo fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $f . '/') ?>" target="_blank"><i class="fa fa-link" aria-hidden="true"></i></a>
1626 </td>
1627 </tr>
1628 <?php
1629 flush();
1630 $ii++;
1631 }
1632 $ik = 6070;
1633 foreach ($files as $f) {
1634 $is_link = is_link($path . '/' . $f);
1635 $img = $is_link ? 'fa fa-file-text-o' : fm_get_file_icon_class($path . '/' . $f);
1636 $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
1637 $filesize_raw = filesize($path . '/' . $f);
1638 $filesize = fm_get_filesize($filesize_raw);
1639 $filelink = '?p=' . urlencode(FM_PATH) . '&view=' . urlencode($f);
1640 $all_files_size += $filesize_raw;
1641 $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
1642 if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
1643 $owner = posix_getpwuid(fileowner($path . '/' . $f));
1644 $group = posix_getgrgid(filegroup($path . '/' . $f));
1645 } else {
1646 $owner = array('name' => '?');
1647 $group = array('name' => '?');
1648 }
1649 ?>
1650 <tr>
1651 <?php if (!FM_READONLY): ?>
1652 <td class="custom-checkbox-td">
1653 <div class="custom-control custom-checkbox">
1654 <input type="checkbox" class="custom-control-input" id="<?php echo $ik ?>" name="file[]" value="<?php echo fm_enc($f) ?>">
1655 <label class="custom-control-label" for="<?php echo $ik ?>"></label>
1656 </div>
1657 </td><?php endif; ?>
1658 <td>
1659 <div class="filename"><a href="<?php echo $filelink ?>" title="File info"><i class="<?php echo $img ?>"></i> <?php echo fm_convert_win($f) ?>
1660 </a><?php echo($is_link ? ' → <i>' . readlink($path . '/' . $f) . '</i>' : '') ?></div>
1661 </td>
1662 <td><span title="<?php printf('%s bytes', $filesize_raw) ?>"><?php echo $filesize ?></span></td>
1663 <td><?php echo $modif ?></td>
1664 <?php if (!FM_IS_WIN): ?>
1665 <td><?php if (!FM_READONLY): ?><a title="<?php echo 'Change Permissions' ?>" href="?p=<?php echo urlencode(FM_PATH) ?>&chmod=<?php echo urlencode($f) ?>"><?php echo $perms ?></a><?php else: ?><?php echo $perms ?><?php endif; ?>
1666 </td>
1667 <td><?php echo fm_enc($owner['name'] . ':' . $group['name']) ?></td>
1668 <?php endif; ?>
1669 <td class="inline-actions">
1670 <?php if (!FM_READONLY): ?>
1671 <a title="<?php echo lng('Delete') ?>" href="?p=<?php echo urlencode(FM_PATH) ?>&del=<?php echo urlencode($f) ?>" onclick="return confirm('Delete file?');"><i class="fa fa-trash-o"></i></a>
1672 <a title="<?php echo lng('Rename') ?>" href="#" onclick="rename('<?php echo fm_enc(FM_PATH) ?>', '<?php echo fm_enc(addslashes($f)) ?>');return false;"><i class="fa fa-pencil-square-o"></i></a>
1673 <a title="<?php echo lng('CopyTo') ?>..."
1674 href="?p=<?php echo urlencode(FM_PATH) ?>&copy=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="fa fa-files-o"></i></a>
1675 <?php endif; ?>
1676 <a title="<?php echo lng('DirectLink') ?>" href="<?php echo fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $f) ?>" target="_blank"><i class="fa fa-link"></i></a>
1677 <a title="<?php echo lng('Download') ?>" href="?p=<?php echo urlencode(FM_PATH) ?>&dl=<?php echo urlencode($f) ?>"><i class="fa fa-download"></i></a>
1678 </td>
1679 </tr>
1680 <?php
1681 flush();
1682 $ik++;
1683 }
1684
1685 if (empty($folders) && empty($files)) {
1686 ?>
1687 <tfoot>
1688 <tr><?php if (!FM_READONLY): ?>
1689 <td></td><?php endif; ?>
1690 <td colspan="<?php echo !FM_IS_WIN ? '6' : '4' ?>"><em><?php echo 'Folder is empty' ?></em></td>
1691 </tr>
1692 </tfoot>
1693 <?php
1694 } else {
1695 ?>
1696 <tfoot>
1697 <tr><?php if (!FM_READONLY): ?>
1698 <td class="gray"></td><?php endif; ?>
1699 <td class="gray" colspan="<?php echo !FM_IS_WIN ? '6' : '4' ?>">
1700 Full size: <span title="<?php printf('%s bytes', $all_files_size) ?>"><?php echo '<span class="badge badge-light">'.fm_get_filesize($all_files_size).'</span>' ?></span>,
1701 <?php echo lng('File').': <span class="badge badge-light">'.$num_files.'</span>' ?>,
1702 <?php echo lng('Folder').': <span class="badge badge-light">'.$num_folders.'</span>' ?>,
1703 <?php echo lng('MemoryUsed').': <span class="badge badge-light">'.fm_get_filesize(@memory_get_usage(true)).'</span>' ?>,
1704 <?php echo lng('PartitionSize').': <span class="badge badge-light">'.fm_get_filesize(@disk_free_space($path)) .'</span> free of <span class="badge badge-light">'.fm_get_filesize(@disk_total_space($path)).'</span>'; ?>
1705 </td>
1706 </tr>
1707 </tfoot>
1708 <?php
1709 }
1710 ?>
1711 </table>
1712 </div>
1713
1714 <div class="row">
1715 <?php if (!FM_READONLY): ?>
1716 <div class="col-xs-12 col-sm-9">
1717 <ul class="list-inline footer-action">
1718 <li class="list-inline-item"> <a href="#/select-all" class="btn btn-small btn-outline-primary btn-2" onclick="select_all();return false;"><i class="fa fa-check-square"></i> <?php echo lng('SelectAll') ?> </a></li>
1719 <li class="list-inline-item"><a href="#/unselect-all" class="btn btn-small btn-outline-primary btn-2" onclick="unselect_all();return false;"><i class="fa fa-window-close"></i> <?php echo lng('UnSelectAll') ?> </a></li>
1720 <li class="list-inline-item"><a href="#/invert-all" class="btn btn-small btn-outline-primary btn-2" onclick="invert_all();return false;"><i class="fa fa-th-list"></i> <?php echo lng('InvertSelection') ?> </a></li>
1721 <li class="list-inline-item"><input type="submit" class="hidden" name="delete" id="a-delete" value="Delete" onclick="return confirm('Delete selected files and folders?')">
1722 <a href="javascript:document.getElementById('a-delete').click();" class="btn btn-small btn-outline-primary btn-2"><i class="fa fa-trash"></i> <?php echo lng('Delete') ?> </a></li>
1723 <li class="list-inline-item"><input type="submit" class="hidden" name="zip" id="a-zip" value="zip" onclick="return confirm('Create archive?')">
1724 <a href="javascript:document.getElementById('a-zip').click();" class="btn btn-small btn-outline-primary btn-2"><i class="fa fa-file-archive-o"></i> <?php echo lng('Zip') ?> </a></li>
1725 <li class="list-inline-item"><input type="submit" class="hidden" name="tar" id="a-tar" value="tar" onclick="return confirm('Create archive?')">
1726 <a href="javascript:document.getElementById('a-tar').click();" class="btn btn-small btn-outline-primary btn-2"><i class="fa fa-file-archive-o"></i> <?php echo lng('Tar') ?> </a></li>
1727 <li class="list-inline-item"><input type="submit" class="hidden" name="copy" id="a-copy" value="Copy">
1728 <a href="javascript:document.getElementById('a-copy').click();" class="btn btn-small btn-outline-primary btn-2"><i class="fa fa-files-o"></i> <?php echo lng('Copy') ?> </a></li>
1729 </ul>
1730 </div>
1731 <div class="col-3 d-none d-sm-block"><a href="https://tinyfilemanager.github.io" target="_blank" class="float-right text-muted">Tiny File Manager <?php echo VERSION; ?></a></div>
1732 <?php else: ?>
1733 <div class="col-12"><a href="https://tinyfilemanager.github.io" target="_blank" class="float-right text-muted">Tiny File Manager <?php echo VERSION; ?></a></div>
1734 <?php endif; ?>
1735 </div>
1736
1737</form>
1738
1739<?php
1740fm_show_footer();
1741
1742//--- END
1743
1744// Functions
1745
1746/**
1747 * Delete file or folder (recursively)
1748 * @param string $path
1749 * @return bool
1750 */
1751function fm_rdelete($path)
1752{
1753 if (is_link($path)) {
1754 return unlink($path);
1755 } elseif (is_dir($path)) {
1756 $objects = scandir($path);
1757 $ok = true;
1758 if (is_array($objects)) {
1759 foreach ($objects as $file) {
1760 if ($file != '.' && $file != '..') {
1761 if (!fm_rdelete($path . '/' . $file)) {
1762 $ok = false;
1763 }
1764 }
1765 }
1766 }
1767 return ($ok) ? rmdir($path) : false;
1768 } elseif (is_file($path)) {
1769 return unlink($path);
1770 }
1771 return false;
1772}
1773
1774/**
1775 * Recursive chmod
1776 * @param string $path
1777 * @param int $filemode
1778 * @param int $dirmode
1779 * @return bool
1780 * @todo Will use in mass chmod
1781 */
1782function fm_rchmod($path, $filemode, $dirmode)
1783{
1784 if (is_dir($path)) {
1785 if (!chmod($path, $dirmode)) {
1786 return false;
1787 }
1788 $objects = scandir($path);
1789 if (is_array($objects)) {
1790 foreach ($objects as $file) {
1791 if ($file != '.' && $file != '..') {
1792 if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) {
1793 return false;
1794 }
1795 }
1796 }
1797 }
1798 return true;
1799 } elseif (is_link($path)) {
1800 return true;
1801 } elseif (is_file($path)) {
1802 return chmod($path, $filemode);
1803 }
1804 return false;
1805}
1806
1807/**
1808 * Safely rename
1809 * @param string $old
1810 * @param string $new
1811 * @return bool|null
1812 */
1813function fm_rename($old, $new)
1814{
1815 $allowed = (FM_EXTENSION) ? explode(',', FM_EXTENSION) : false;
1816
1817 $ext = pathinfo($new, PATHINFO_EXTENSION);
1818 $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;
1819
1820 if(!$isFileAllowed) return false;
1821
1822 return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null;
1823}
1824
1825/**
1826 * Copy file or folder (recursively).
1827 * @param string $path
1828 * @param string $dest
1829 * @param bool $upd Update files
1830 * @param bool $force Create folder with same names instead file
1831 * @return bool
1832 */
1833function fm_rcopy($path, $dest, $upd = true, $force = true)
1834{
1835 if (is_dir($path)) {
1836 if (!fm_mkdir($dest, $force)) {
1837 return false;
1838 }
1839 $objects = scandir($path);
1840 $ok = true;
1841 if (is_array($objects)) {
1842 foreach ($objects as $file) {
1843 if ($file != '.' && $file != '..') {
1844 if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) {
1845 $ok = false;
1846 }
1847 }
1848 }
1849 }
1850 return $ok;
1851 } elseif (is_file($path)) {
1852 return fm_copy($path, $dest, $upd);
1853 }
1854 return false;
1855}
1856
1857/**
1858 * Safely create folder
1859 * @param string $dir
1860 * @param bool $force
1861 * @return bool
1862 */
1863function fm_mkdir($dir, $force)
1864{
1865 if (file_exists($dir)) {
1866 if (is_dir($dir)) {
1867 return $dir;
1868 } elseif (!$force) {
1869 return false;
1870 }
1871 unlink($dir);
1872 }
1873 return mkdir($dir, 0777, true);
1874}
1875
1876/**
1877 * Safely copy file
1878 * @param string $f1
1879 * @param string $f2
1880 * @param bool $upd
1881 * @return bool
1882 */
1883function fm_copy($f1, $f2, $upd)
1884{
1885 $time1 = filemtime($f1);
1886 if (file_exists($f2)) {
1887 $time2 = filemtime($f2);
1888 if ($time2 >= $time1 && $upd) {
1889 return false;
1890 }
1891 }
1892 $ok = copy($f1, $f2);
1893 if ($ok) {
1894 touch($f2, $time1);
1895 }
1896 return $ok;
1897}
1898
1899/**
1900 * Get mime type
1901 * @param string $file_path
1902 * @return mixed|string
1903 */
1904function fm_get_mime_type($file_path)
1905{
1906 if (function_exists('finfo_open')) {
1907 $finfo = finfo_open(FILEINFO_MIME_TYPE);
1908 $mime = finfo_file($finfo, $file_path);
1909 finfo_close($finfo);
1910 return $mime;
1911 } elseif (function_exists('mime_content_type')) {
1912 return mime_content_type($file_path);
1913 } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) {
1914 $file = escapeshellarg($file_path);
1915 $mime = shell_exec('file -bi ' . $file);
1916 return $mime;
1917 } else {
1918 return '--';
1919 }
1920}
1921
1922/**
1923 * HTTP Redirect
1924 * @param string $url
1925 * @param int $code
1926 */
1927function fm_redirect($url, $code = 302)
1928{
1929 header('Location: ' . $url, true, $code);
1930 exit;
1931}
1932
1933/**
1934 * Clean path
1935 * @param string $path
1936 * @return string
1937 */
1938function fm_clean_path($path)
1939{
1940 $path = trim($path);
1941 $path = trim($path, '\\/');
1942 $path = str_replace(array('../', '..\\'), '', $path);
1943 if ($path == '..') {
1944 $path = '';
1945 }
1946 return str_replace('\\', '/', $path);
1947}
1948
1949/**
1950 * Get parent path
1951 * @param string $path
1952 * @return bool|string
1953 */
1954function fm_get_parent_path($path)
1955{
1956 $path = fm_clean_path($path);
1957 if ($path != '') {
1958 $array = explode('/', $path);
1959 if (count($array) > 1) {
1960 $array = array_slice($array, 0, -1);
1961 return implode('/', $array);
1962 }
1963 return '';
1964 }
1965 return false;
1966}
1967
1968/*
1969 * get language translations from json file
1970 * @param int $tr
1971 * @return array
1972 */
1973function fm_get_translations($tr) {
1974 try {
1975 $content = @file_get_contents('translation.json');
1976 if($content !== FALSE) {
1977 $lng = json_decode($content, TRUE);
1978 global $lang_list;
1979 foreach ($lng["language"] as $key => $value)
1980 {
1981 $code = $value["code"];
1982 $lang_list[$code] = $value["name"];
1983 if ($tr)
1984 $tr[$code] = $value["translation"];
1985 }
1986 return $tr;
1987 }
1988
1989 }
1990 catch (Exception $e) {
1991 echo $e;
1992 }
1993}
1994
1995/**
1996 * Get nice filesize
1997 * @param int $size
1998 * @return string
1999 */
2000function fm_get_filesize($size)
2001{
2002 if ($size < 1000) {
2003 return sprintf('%s B', $size);
2004 } elseif (($size / 1024) < 1000) {
2005 return sprintf('%s KB', round(($size / 1024), 2));
2006 } elseif (($size / 1024 / 1024) < 1000) {
2007 return sprintf('%s MB', round(($size / 1024 / 1024), 2));
2008 } elseif (($size / 1024 / 1024 / 1024) < 1000) {
2009 return sprintf('%s GB', round(($size / 1024 / 1024 / 1024), 2));
2010 } else {
2011 return sprintf('%s TB', round(($size / 1024 / 1024 / 1024 / 1024), 2));
2012 }
2013}
2014
2015/**
2016 * Get info about zip archive
2017 * @param string $path
2018 * @return array|bool
2019 */
2020function fm_get_zif_info($path, $ext) {
2021 if ($ext == 'zip' && function_exists('zip_open')) {
2022 $arch = zip_open($path);
2023 if ($arch) {
2024 $filenames = array();
2025 while ($zip_entry = zip_read($arch)) {
2026 $zip_name = zip_entry_name($zip_entry);
2027 $zip_folder = substr($zip_name, -1) == '/';
2028 $filenames[] = array(
2029 'name' => $zip_name,
2030 'filesize' => zip_entry_filesize($zip_entry),
2031 'compressed_size' => zip_entry_compressedsize($zip_entry),
2032 'folder' => $zip_folder
2033 //'compression_method' => zip_entry_compressionmethod($zip_entry),
2034 );
2035 }
2036 zip_close($arch);
2037 return $filenames;
2038 }
2039 } elseif($ext == 'tar' && class_exists('PharData')) {
2040 $archive = new PharData($path);
2041 $filenames = array();
2042 foreach(new RecursiveIteratorIterator($archive) as $file) {
2043 $parent_info = $file->getPathInfo();
2044 $zip_name = str_replace("phar://".$path, '', $file->getPathName());
2045 $zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0);
2046 $zip_folder = $parent_info->getFileName();
2047 $zip_info = new SplFileInfo($file);
2048 $filenames[] = array(
2049 'name' => $zip_name,
2050 'filesize' => $zip_info->getSize(),
2051 'compressed_size' => $file->getCompressedSize(),
2052 'folder' => $zip_folder
2053 );
2054 }
2055 return $filenames;
2056 }
2057 return false;
2058}
2059
2060/**
2061 * Encode html entities
2062 * @param string $text
2063 * @return string
2064 */
2065function fm_enc($text)
2066{
2067 return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
2068}
2069
2070/**
2071 * Save message in session
2072 * @param string $msg
2073 * @param string $status
2074 */
2075function fm_set_msg($msg, $status = 'ok')
2076{
2077 $_SESSION[FM_SESSION_ID]['message'] = $msg;
2078 $_SESSION[FM_SESSION_ID]['status'] = $status;
2079}
2080
2081/**
2082 * Check if string is in UTF-8
2083 * @param string $string
2084 * @return int
2085 */
2086function fm_is_utf8($string)
2087{
2088 return preg_match('//u', $string);
2089}
2090
2091/**
2092 * Convert file name to UTF-8 in Windows
2093 * @param string $filename
2094 * @return string
2095 */
2096function fm_convert_win($filename)
2097{
2098 if (FM_IS_WIN && function_exists('iconv')) {
2099 $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename);
2100 }
2101 return $filename;
2102}
2103
2104/**
2105 * @param $obj
2106 * @return array
2107 */
2108function fm_object_to_array($obj)
2109{
2110 if (!is_object($obj) && !is_array($obj)) {
2111 return $obj;
2112 }
2113 if (is_object($obj)) {
2114 $obj = get_object_vars($obj);
2115 }
2116 return array_map('fm_object_to_array', $obj);
2117}
2118
2119/**
2120 * Get CSS classname for file
2121 * @param string $path
2122 * @return string
2123 */
2124function fm_get_file_icon_class($path)
2125{
2126 // get extension
2127 $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
2128
2129 switch ($ext) {
2130 case 'ico':
2131 case 'gif':
2132 case 'jpg':
2133 case 'jpeg':
2134 case 'jpc':
2135 case 'jp2':
2136 case 'jpx':
2137 case 'xbm':
2138 case 'wbmp':
2139 case 'png':
2140 case 'bmp':
2141 case 'tif':
2142 case 'tiff':
2143 case 'svg':
2144 $img = 'fa fa-picture-o';
2145 break;
2146 case 'passwd':
2147 case 'ftpquota':
2148 case 'sql':
2149 case 'js':
2150 case 'json':
2151 case 'sh':
2152 case 'config':
2153 case 'twig':
2154 case 'tpl':
2155 case 'md':
2156 case 'gitignore':
2157 case 'c':
2158 case 'cpp':
2159 case 'cs':
2160 case 'py':
2161 case 'map':
2162 case 'lock':
2163 case 'dtd':
2164 $img = 'fa fa-file-code-o';
2165 break;
2166 case 'txt':
2167 case 'ini':
2168 case 'conf':
2169 case 'log':
2170 case 'htaccess':
2171 $img = 'fa fa-file-text-o';
2172 break;
2173 case 'css':
2174 case 'less':
2175 case 'sass':
2176 case 'scss':
2177 $img = 'fa fa-css3';
2178 break;
2179 case 'zip':
2180 case 'rar':
2181 case 'gz':
2182 case 'tar':
2183 case '7z':
2184 $img = 'fa fa-file-archive-o';
2185 break;
2186 case 'php':
2187 case 'php4':
2188 case 'php5':
2189 case 'phps':
2190 case 'phtml':
2191 $img = 'fa fa-code';
2192 break;
2193 case 'htm':
2194 case 'html':
2195 case 'shtml':
2196 case 'xhtml':
2197 $img = 'fa fa-html5';
2198 break;
2199 case 'xml':
2200 case 'xsl':
2201 $img = 'fa fa-file-excel-o';
2202 break;
2203 case 'wav':
2204 case 'mp3':
2205 case 'mp2':
2206 case 'm4a':
2207 case 'aac':
2208 case 'ogg':
2209 case 'oga':
2210 case 'wma':
2211 case 'mka':
2212 case 'flac':
2213 case 'ac3':
2214 case 'tds':
2215 $img = 'fa fa-music';
2216 break;
2217 case 'm3u':
2218 case 'm3u8':
2219 case 'pls':
2220 case 'cue':
2221 $img = 'fa fa-headphones';
2222 break;
2223 case 'avi':
2224 case 'mpg':
2225 case 'mpeg':
2226 case 'mp4':
2227 case 'm4v':
2228 case 'flv':
2229 case 'f4v':
2230 case 'ogm':
2231 case 'ogv':
2232 case 'mov':
2233 case 'mkv':
2234 case '3gp':
2235 case 'asf':
2236 case 'wmv':
2237 $img = 'fa fa-file-video-o';
2238 break;
2239 case 'eml':
2240 case 'msg':
2241 $img = 'fa fa-envelope-o';
2242 break;
2243 case 'xls':
2244 case 'xlsx':
2245 $img = 'fa fa-file-excel-o';
2246 break;
2247 case 'csv':
2248 $img = 'fa fa-file-text-o';
2249 break;
2250 case 'bak':
2251 $img = 'fa fa-clipboard';
2252 break;
2253 case 'doc':
2254 case 'docx':
2255 $img = 'fa fa-file-word-o';
2256 break;
2257 case 'ppt':
2258 case 'pptx':
2259 $img = 'fa fa-file-powerpoint-o';
2260 break;
2261 case 'ttf':
2262 case 'ttc':
2263 case 'otf':
2264 case 'woff':
2265 case 'woff2':
2266 case 'eot':
2267 case 'fon':
2268 $img = 'fa fa-font';
2269 break;
2270 case 'pdf':
2271 $img = 'fa fa-file-pdf-o';
2272 break;
2273 case 'psd':
2274 case 'ai':
2275 case 'eps':
2276 case 'fla':
2277 case 'swf':
2278 $img = 'fa fa-file-image-o';
2279 break;
2280 case 'exe':
2281 case 'msi':
2282 $img = 'fa fa-file-o';
2283 break;
2284 case 'bat':
2285 $img = 'fa fa-terminal';
2286 break;
2287 default:
2288 $img = 'fa fa-info-circle';
2289 }
2290
2291 return $img;
2292}
2293
2294/**
2295 * Get image files extensions
2296 * @return array
2297 */
2298function fm_get_image_exts()
2299{
2300 return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd');
2301}
2302
2303/**
2304 * Get video files extensions
2305 * @return array
2306 */
2307function fm_get_video_exts()
2308{
2309 return array('webm', 'mp4', 'm4v', 'ogm', 'ogv', 'mov');
2310}
2311
2312/**
2313 * Get audio files extensions
2314 * @return array
2315 */
2316function fm_get_audio_exts()
2317{
2318 return array('wav', 'mp3', 'ogg', 'm4a');
2319}
2320
2321/**
2322 * Get text file extensions
2323 * @return array
2324 */
2325function fm_get_text_exts()
2326{
2327 return array(
2328 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'json', 'sh', 'config',
2329 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue',
2330 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py',
2331 'map', 'lock', 'dtd', 'svg',
2332 );
2333}
2334
2335/**
2336 * Get mime types of text files
2337 * @return array
2338 */
2339function fm_get_text_mimes()
2340{
2341 return array(
2342 'application/xml',
2343 'application/javascript',
2344 'application/x-javascript',
2345 'image/svg+xml',
2346 'message/rfc822',
2347 );
2348}
2349
2350/**
2351 * Get file names of text files w/o extensions
2352 * @return array
2353 */
2354function fm_get_text_names()
2355{
2356 return array(
2357 'license',
2358 'readme',
2359 'authors',
2360 'contributors',
2361 'changelog',
2362 );
2363}
2364
2365/**
2366 * Get online docs viewer supported files extensions
2367 * @return array
2368 */
2369function fm_get_onlineViewer_exts()
2370{
2371 return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar');
2372}
2373
2374/**
2375 * Class to work with zip files (using ZipArchive)
2376 */
2377class FM_Zipper
2378{
2379 private $zip;
2380
2381 public function __construct()
2382 {
2383 $this->zip = new ZipArchive();
2384 }
2385
2386 /**
2387 * Create archive with name $filename and files $files (RELATIVE PATHS!)
2388 * @param string $filename
2389 * @param array|string $files
2390 * @return bool
2391 */
2392 public function create($filename, $files)
2393 {
2394 $res = $this->zip->open($filename, ZipArchive::CREATE);
2395 if ($res !== true) {
2396 return false;
2397 }
2398 if (is_array($files)) {
2399 foreach ($files as $f) {
2400 if (!$this->addFileOrDir($f)) {
2401 $this->zip->close();
2402 return false;
2403 }
2404 }
2405 $this->zip->close();
2406 return true;
2407 } else {
2408 if ($this->addFileOrDir($files)) {
2409 $this->zip->close();
2410 return true;
2411 }
2412 return false;
2413 }
2414 }
2415
2416 /**
2417 * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS)
2418 * @param string $filename
2419 * @param string $path
2420 * @return bool
2421 */
2422 public function unzip($filename, $path)
2423 {
2424 $res = $this->zip->open($filename);
2425 if ($res !== true) {
2426 return false;
2427 }
2428 if ($this->zip->extractTo($path)) {
2429 $this->zip->close();
2430 return true;
2431 }
2432 return false;
2433 }
2434
2435 /**
2436 * Add file/folder to archive
2437 * @param string $filename
2438 * @return bool
2439 */
2440 private function addFileOrDir($filename)
2441 {
2442 if (is_file($filename)) {
2443 return $this->zip->addFile($filename);
2444 } elseif (is_dir($filename)) {
2445 return $this->addDir($filename);
2446 }
2447 return false;
2448 }
2449
2450 /**
2451 * Add folder recursively
2452 * @param string $path
2453 * @return bool
2454 */
2455 private function addDir($path)
2456 {
2457 if (!$this->zip->addEmptyDir($path)) {
2458 return false;
2459 }
2460 $objects = scandir($path);
2461 if (is_array($objects)) {
2462 foreach ($objects as $file) {
2463 if ($file != '.' && $file != '..') {
2464 if (is_dir($path . '/' . $file)) {
2465 if (!$this->addDir($path . '/' . $file)) {
2466 return false;
2467 }
2468 } elseif (is_file($path . '/' . $file)) {
2469 if (!$this->zip->addFile($path . '/' . $file)) {
2470 return false;
2471 }
2472 }
2473 }
2474 }
2475 return true;
2476 }
2477 return false;
2478 }
2479}
2480
2481/**
2482 * Class to work with Tar files (using PharData)
2483 */
2484class FM_Zipper_Tar
2485{
2486 private $tar;
2487
2488 public function __construct()
2489 {
2490 $this->tar = null;
2491 }
2492
2493 /**
2494 * Create archive with name $filename and files $files (RELATIVE PATHS!)
2495 * @param string $filename
2496 * @param array|string $files
2497 * @return bool
2498 */
2499 public function create($filename, $files)
2500 {
2501 $this->tar = new PharData($filename);
2502 if (is_array($files)) {
2503 foreach ($files as $f) {
2504 if (!$this->addFileOrDir($f)) {
2505 return false;
2506 }
2507 }
2508 return true;
2509 } else {
2510 if ($this->addFileOrDir($files)) {
2511 return true;
2512 }
2513 return false;
2514 }
2515 }
2516
2517 /**
2518 * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS)
2519 * @param string $filename
2520 * @param string $path
2521 * @return bool
2522 */
2523 public function unzip($filename, $path)
2524 {
2525 $res = $this->tar->open($filename);
2526 if ($res !== true) {
2527 return false;
2528 }
2529 if ($this->tar->extractTo($path)) {
2530 return true;
2531 }
2532 return false;
2533 }
2534
2535 /**
2536 * Add file/folder to archive
2537 * @param string $filename
2538 * @return bool
2539 */
2540 private function addFileOrDir($filename)
2541 {
2542 if (is_file($filename)) {
2543 return $this->tar->addFile($filename);
2544 } elseif (is_dir($filename)) {
2545 return $this->addDir($filename);
2546 }
2547 return false;
2548 }
2549
2550 /**
2551 * Add folder recursively
2552 * @param string $path
2553 * @return bool
2554 */
2555 private function addDir($path)
2556 {
2557 $objects = scandir($path);
2558 if (is_array($objects)) {
2559 foreach ($objects as $file) {
2560 if ($file != '.' && $file != '..') {
2561 if (is_dir($path . '/' . $file)) {
2562 if (!$this->addDir($path . '/' . $file)) {
2563 return false;
2564 }
2565 } elseif (is_file($path . '/' . $file)) {
2566 try {
2567 $this->tar->addFile($path . '/' . $file);
2568 } catch (Exception $e) {
2569 return false;
2570 }
2571 }
2572 }
2573 }
2574 return true;
2575 }
2576 return false;
2577 }
2578}
2579
2580
2581
2582/**
2583 * Save Configuration
2584 */
2585 class FM_Config
2586{
2587 var $data;
2588
2589 function __construct()
2590 {
2591 global $root_path, $root_url, $CONFIG;
2592 $fm_url = $root_url.$_SERVER["PHP_SELF"];
2593 $this->data = array(
2594 'lang' => 'en',
2595 'error_reporting' => true,
2596 'show_hidden' => true
2597 );
2598 $data = false;
2599 if (strlen($CONFIG)) {
2600 $data = fm_object_to_array(json_decode($CONFIG));
2601 } else {
2602 $msg = 'Tiny File Manager<br>Error: Cannot load configuration';
2603 if (substr($fm_url, -1) == '/') {
2604 $fm_url = rtrim($fm_url, '/');
2605 $msg .= '<br>';
2606 $msg .= '<br>Seems like you have a trailing slash on the URL.';
2607 $msg .= '<br>Try this link: <a href="' . $fm_url . '">' . $fm_url . '</a>';
2608 }
2609 die($msg);
2610 }
2611 if (is_array($data) && count($data)) $this->data = $data;
2612 else $this->save();
2613 }
2614
2615 function save()
2616 {
2617 global $root_path;
2618 $fm_file = $root_path.$_SERVER["PHP_SELF"];
2619 $var_name = '$CONFIG';
2620 $var_value = var_export(json_encode($this->data), true);
2621 $config_string = "<?php" . chr(13) . chr(10) . "//Default Configuration".chr(13) . chr(10)."$var_name = $var_value;" . chr(13) . chr(10);
2622 if (file_exists($fm_file)) {
2623 $lines = file($fm_file);
2624 if ($fh = @fopen($fm_file, "w")) {
2625 @fputs($fh, $config_string, strlen($config_string));
2626 for ($x = 3; $x < count($lines); $x++) {
2627 @fputs($fh, $lines[$x], strlen($lines[$x]));
2628 }
2629 @fclose($fh);
2630 }
2631 }
2632 }
2633}
2634
2635//--- templates functions
2636
2637/**
2638 * Show nav block
2639 * @param string $path
2640 */
2641function fm_show_nav_path($path)
2642{
2643 global $lang, $sticky_navbar;
2644 $isStickyNavBar = $sticky_navbar ? 'fixed-top' : '';
2645 ?>
2646 <nav class="navbar navbar-expand-lg navbar-light bg-white mb-4 main-nav <?php echo $isStickyNavBar ?>">
2647 <a class="navbar-brand" href=""> <?php echo lng('AppTitle') ?> </a>
2648 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
2649 <span class="navbar-toggler-icon"></span>
2650 </button>
2651 <div class="collapse navbar-collapse" id="navbarSupportedContent">
2652
2653 <?php
2654 $path = fm_clean_path($path);
2655 $root_url = "<a href='?p='><i class='fa fa-home' aria-hidden='true' title='" . FM_ROOT_PATH . "'></i></a>";
2656 $sep = '<i class="bread-crumb"> / </i>';
2657 if ($path != '') {
2658 $exploded = explode('/', $path);
2659 $count = count($exploded);
2660 $array = array();
2661 $parent = '';
2662 for ($i = 0; $i < $count; $i++) {
2663 $parent = trim($parent . '/' . $exploded[$i], '/');
2664 $parent_enc = urlencode($parent);
2665 $array[] = "<a href='?p={$parent_enc}'>" . fm_enc(fm_convert_win($exploded[$i])) . "</a>";
2666 }
2667 $root_url .= $sep . implode($sep, $array);
2668 }
2669 echo '<div class="col-xs-6 col-sm-5">' . $root_url . '</div>';
2670 ?>
2671
2672 <div class="col-xs-6 col-sm-7 text-right">
2673 <ul class="navbar-nav mr-auto float-right">
2674 <?php if (!FM_READONLY): ?>
2675 <li class="nav-item mr-2">
2676 <div class="input-group input-group-sm mr-1" style="margin-top:4px;">
2677 <input type="text" class="form-control" placeholder="<?php echo lng('Search') ?>" aria-label="<?php echo lng('Search') ?>" aria-describedby="search-addon2" id="search-addon">
2678 <div class="input-group-append">
2679 <span class="input-group-text" id="search-addon2"><i class="fa fa-search"></i></span>
2680 </div>
2681 </div>
2682 </li>
2683 <li class="nav-item">
2684 <a title="<?php echo lng('Upload') ?>" class="nav-link" href="?p=<?php echo urlencode(FM_PATH) ?>&upload"><i class="fa fa-cloud-upload" aria-hidden="true"></i> <?php echo lng('Upload') ?></a>
2685 </li>
2686 <li class="nav-item">
2687 <a title="<?php echo lng('NewItem') ?>" class="nav-link" href="#createNewItem" data-toggle="modal" data-target="#createNewItem"><i class="fa fa-plus-square"></i> <?php echo lng('NewItem') ?></a>
2688 </li>
2689 <?php endif; ?>
2690 <?php if (FM_USE_AUTH): ?>
2691 <li class="nav-item avatar dropdown">
2692 <a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink-5" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i class="fa fa-user-circle"></i> <?php if(isset($_SESSION[FM_SESSION_ID]['logged'])) { echo $_SESSION[FM_SESSION_ID]['logged']; } ?></a>
2693 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink-5">
2694 <?php if (!FM_READONLY): ?>
2695 <a title="<?php echo lng('Settings') ?>" class="dropdown-item nav-link" href="?p=<?php echo urlencode(FM_PATH) ?>&settings=1"><i class="fa fa-cog" aria-hidden="true"></i> <?php echo lng('Settings') ?></a>
2696 <?php endif ?>
2697 <a title="<?php echo lng('Help') ?>" class="dropdown-item nav-link" href="?p=<?php echo urlencode(FM_PATH) ?>&help=2"><i class="fa fa-exclamation-circle" aria-hidden="true"></i> <?php echo lng('Help') ?></a>
2698 <a title="<?php echo lng('Logout') ?>" class="dropdown-item nav-link" href="?logout=1"><i class="fa fa-sign-out" aria-hidden="true"></i> <?php echo lng('Logout') ?></a>
2699 </div>
2700 </li>
2701 <?php endif; ?>
2702 </ul>
2703 </div>
2704 </div>
2705 </nav>
2706 <?php
2707}
2708
2709/**
2710 * Show message from session
2711 */
2712function fm_show_message()
2713{
2714 if (isset($_SESSION[FM_SESSION_ID]['message'])) {
2715 $class = isset($_SESSION[FM_SESSION_ID]['status']) ? $_SESSION[FM_SESSION_ID]['status'] : 'ok';
2716 echo '<p class="message ' . $class . '">' . $_SESSION[FM_SESSION_ID]['message'] . '</p>';
2717 unset($_SESSION[FM_SESSION_ID]['message']);
2718 unset($_SESSION[FM_SESSION_ID]['status']);
2719 }
2720}
2721
2722/**
2723 * Show page header in Login Form
2724 */
2725function fm_show_header_login()
2726{
2727$sprites_ver = '20160315';
2728header("Content-Type: text/html; charset=utf-8");
2729header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
2730header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
2731header("Pragma: no-cache");
2732
2733global $lang;
2734?>
2735<!DOCTYPE html>
2736<html lang="en">
2737<head>
2738 <meta charset="utf-8">
2739 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
2740 <meta name="description" content="Web based File Manager in PHP, Manage your files efficiently and easily with Tiny File Manager">
2741 <meta name="author" content="CCP Programmers">
2742 <meta name="robots" content="noindex, nofollow">
2743 <meta name="googlebot" content="noindex">
2744 <link rel="icon" href="<?php echo FM_SELF_URL ?>?img=favicon" type="image/png">
2745 <title>H3K | Tiny File Manager</title>
2746 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
2747 <style>
2748 body.fm-login-page{background-color:#f7f9fb;font-size:14px}
2749 .fm-login-page .brand{width:121px;overflow:hidden;margin:0 auto;margin:40px auto;margin-bottom:0;position:relative;z-index:1}
2750 .fm-login-page .brand img{width:100%}
2751 .fm-login-page .card-wrapper{width:360px}
2752 .fm-login-page .card{border-color:transparent;box-shadow:0 4px 8px rgba(0,0,0,.05)}
2753 .fm-login-page .card-title{margin-bottom:1.5rem;font-size:24px;font-weight:300;letter-spacing:-.5px}
2754 .fm-login-page .form-control{border-width:2.3px}
2755 .fm-login-page .form-group label{width:100%}
2756 .fm-login-page .btn.btn-block{padding:12px 10px}
2757 .fm-login-page .footer{margin:40px 0;color:#888;text-align:center}
2758 @media screen and (max-width: 425px) {
2759 .fm-login-page .card-wrapper{width:90%;margin:0 auto}
2760 }
2761 @media screen and (max-width: 320px) {
2762 .fm-login-page .card.fat{padding:0}
2763 .fm-login-page .card.fat .card-body{padding:15px}
2764 }
2765 .message{padding:4px 7px;border:1px solid #ddd;background-color:#fff}
2766 .message.ok{border-color:green;color:green}
2767 .message.error{border-color:red;color:red}
2768 .message.alert{border-color:orange;color:orange}
2769 </style>
2770</head>
2771<body class="fm-login-page">
2772<div id="wrapper" class="container-fluid">
2773
2774 <?php
2775 }
2776
2777 /**
2778 * Show page footer in Login Form
2779 */
2780 function fm_show_footer_login()
2781 {
2782 ?>
2783</div>
2784<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js"></script>
2785<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
2786</body>
2787</html>
2788<?php
2789}
2790
2791/**
2792 * Show Header after login
2793 */
2794function fm_show_header()
2795{
2796$sprites_ver = '20160315';
2797header("Content-Type: text/html; charset=utf-8");
2798header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
2799header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
2800header("Pragma: no-cache");
2801
2802global $lang, $sticky_navbar;
2803$isStickyNavBar = $sticky_navbar ? 'navbar-fixed' : 'navbar-normal';
2804?>
2805<!DOCTYPE html>
2806<html>
2807<head>
2808 <meta charset="utf-8">
2809 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
2810 <meta name="description" content="Web based File Manager in PHP, Manage your files efficiently and easily with Tiny File Manager">
2811 <meta name="author" content="CCP Programmers">
2812 <meta name="robots" content="noindex, nofollow">
2813 <meta name="googlebot" content="noindex">
2814 <link rel="icon" href="<?php echo FM_SELF_URL ?>?img=favicon" type="image/png">
2815 <title>H3K | Tiny File Manager</title>
2816 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
2817 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
2818 <?php if (isset($_GET['view']) && FM_USE_HIGHLIGHTJS): ?>
2819 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/<?php echo FM_HIGHLIGHTJS_STYLE ?>.min.css">
2820 <?php endif; ?>
2821 <style>
2822 body {
2823 font-size: 14px;
2824 color: #222;
2825 background: #F7F7F7;
2826 }
2827 body.navbar-fixed {
2828 margin-top: 55px;
2829 }
2830 a:hover, a:visited, a:focus {
2831 text-decoration: none !important;
2832 }
2833 * {
2834 -webkit-border-radius: 0 !important;
2835 -moz-border-radius: 0 !important;
2836 border-radius: 0 !important;
2837 }
2838 .filename, td, th {
2839 white-space: nowrap
2840 }
2841 .navbar-brand {
2842 font-weight: bold;
2843 }
2844 .nav-item.avatar a {
2845 cursor: pointer;
2846 text-transform: capitalize;
2847 }
2848 .nav-item.avatar a > i {
2849 font-size: 15px;
2850 }
2851 .nav-item.avatar .dropdown-menu a {
2852 font-size: 13px;
2853 }
2854 #search-addon {
2855 font-size: 12px;
2856 border-right-width: 0;
2857 }
2858 #search-addon2 {
2859 background: transparent;
2860 border-left: 0;
2861 }
2862 .bread-crumb {
2863 color: #cccccc;
2864 font-style: normal;
2865 }
2866 #main-table .filename a {
2867 color: #222222;
2868 }
2869 .table td, .table th {
2870 vertical-align: middle !important;
2871 }
2872 .table .custom-checkbox-td .custom-control.custom-checkbox, .table .custom-checkbox-header .custom-control.custom-checkbox {
2873 padding: 0;
2874 min-width: 18px;
2875 }
2876 .hidden {
2877 display: none
2878 }
2879 pre.with-hljs {
2880 padding: 0
2881 }
2882 pre.with-hljs code {
2883 margin: 0;
2884 border: 0;
2885 overflow: visible
2886 }
2887 code.maxheight, pre.maxheight {
2888 max-height: 512px
2889 }
2890 .fa.fa-caret-right {
2891 font-size: 1.2em;
2892 margin: 0 4px;
2893 vertical-align: middle;
2894 color: #ececec
2895 }
2896 .fa.fa-home {
2897 font-size: 1.3em;
2898 vertical-align: bottom
2899 }
2900 .path {
2901 margin-bottom: 10px
2902 }
2903 form.dropzone {
2904 min-height: 200px;
2905 border: 2px dashed #007bff;
2906 line-height: 6rem;
2907 }
2908 .right {
2909 text-align: right
2910 }
2911 .center, .close, .login-form {
2912 text-align: center
2913 }
2914 .message {
2915 padding: 4px 7px;
2916 border: 1px solid #ddd;
2917 background-color: #fff
2918 }
2919 .message.ok {
2920 border-color: green;
2921 color: green
2922 }
2923 .message.error {
2924 border-color: red;
2925 color: red
2926 }
2927 .message.alert {
2928 border-color: orange;
2929 color: orange
2930 }
2931 .preview-img {
2932 max-width: 100%;
2933 background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKklEQVR42mL5//8/Azbw+PFjrOJMDCSCUQ3EABZc4S0rKzsaSvTTABBgAMyfCMsY4B9iAAAAAElFTkSuQmCC)
2934 }
2935 .inline-actions > a > i {
2936 font-size: 1em;
2937 margin-left: 5px;
2938 background: #3785c1;
2939 color: #fff;
2940 padding: 3px;
2941 border-radius: 3px
2942 }
2943 .preview-video {
2944 position: relative;
2945 max-width: 100%;
2946 height: 0;
2947 padding-bottom: 62.5%;
2948 margin-bottom: 10px
2949 }
2950 .preview-video video {
2951 position: absolute;
2952 width: 100%;
2953 height: 100%;
2954 left: 0;
2955 top: 0;
2956 background: #000
2957 }
2958 .compact-table {
2959 border: 0;
2960 width: auto
2961 }
2962 .compact-table td, .compact-table th {
2963 width: 100px;
2964 border: 0;
2965 text-align: center
2966 }
2967 .compact-table tr:hover td {
2968 background-color: #fff
2969 }
2970 .filename {
2971 max-width: 420px;
2972 overflow: hidden;
2973 text-overflow: ellipsis
2974 }
2975 .break-word {
2976 word-wrap: break-word;
2977 margin-left: 30px
2978 }
2979 .break-word.float-left a {
2980 color: #7d7d7d
2981 }
2982 .break-word + .float-right {
2983 padding-right: 30px;
2984 position: relative
2985 }
2986 .break-word + .float-right > a {
2987 color: #7d7d7d;
2988 font-size: 1.2em;
2989 margin-right: 4px
2990 }
2991 #editor {
2992 position: absolute;
2993 right: 15px;
2994 top: 100px;
2995 bottom: 15px;
2996 left: 15px
2997 }
2998 @media (max-width:481px) {
2999 #editor {
3000 top: 150px;
3001 }
3002 }
3003 #normal-editor {
3004 border-radius: 3px;
3005 border-width: 2px;
3006 padding: 10px;
3007 outline: none;
3008 }
3009 .btn-2 {
3010 border-radius: 0;
3011 padding: 3px 6px;
3012 font-size: small;
3013 }
3014 li.file:before,li.folder:before{font:normal normal normal 14px/1 FontAwesome;content:"\f016";margin-right:5px}li.folder:before{content:"\f114"}i.fa.fa-folder-o{color:#0157b3}i.fa.fa-picture-o{color:#26b99a}i.fa.fa-file-archive-o{color:#da7d7d}.btn-2 i.fa.fa-file-archive-o{color:inherit}i.fa.fa-css3{color:#f36fa0}i.fa.fa-file-code-o{color:#007bff}i.fa.fa-code{color:#cc4b4c}i.fa.fa-file-text-o{color:#0096e6}i.fa.fa-html5{color:#d75e72}i.fa.fa-file-excel-o{color:#09c55d}i.fa.fa-file-powerpoint-o{color:#f6712e}
3015 i.go-back {
3016 font-size: 1.2em;
3017 color: #007bff;
3018 }
3019 .main-nav {
3020 padding: 0.2rem 1rem;
3021 box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2)
3022 }
3023 .dataTables_filter {
3024 display: none;
3025 }
3026 table.dataTable thead .sorting {
3027 cursor: pointer;
3028 background-repeat: no-repeat;
3029 background-position: center right;
3030 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7XQMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC');
3031 }
3032 table.dataTable thead .sorting_asc {
3033 cursor: pointer;
3034 background-repeat: no-repeat;
3035 background-position: center right;
3036 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==');
3037 }
3038 table.dataTable thead .sorting_desc {
3039 cursor: pointer;
3040 background-repeat: no-repeat;
3041 background-position: center right;
3042 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=');
3043 }
3044 table.dataTable thead tr:first-child th.custom-checkbox-header:first-child{
3045 background-image: none;
3046 }
3047 .footer-action li {
3048 margin-bottom: 10px;
3049 }
3050 .app-v-title {
3051 font-size: 24px;
3052 font-weight: 300;
3053 letter-spacing: -.5px;
3054 text-transform: uppercase;
3055 }
3056 hr.custom-hr {
3057 border-top: 1px dashed #8c8b8b;
3058 border-bottom: 1px dashed #fff;
3059 }
3060 @media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio: 2) { .navbar-collapse .col-xs-6.text-right { padding: 0; } }
3061 .btn.active.focus,.btn.active:focus,.btn.focus,.btn.focus:active,.btn:active:focus,.btn:focus{outline:0!important;outline-offset:0!important;background-image:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}
3062 .lds-facebook{display:none;position:relative;width:64px;height:64px}.lds-facebook div,.lds-facebook.show-me{display:inline-block}.lds-facebook div{position:absolute;left:6px;width:13px;background:#007bff;animation:lds-facebook 1.2s cubic-bezier(0,.5,.5,1) infinite}.lds-facebook div:nth-child(1){left:6px;animation-delay:-.24s}.lds-facebook div:nth-child(2){left:26px;animation-delay:-.12s}.lds-facebook div:nth-child(3){left:45px;animation-delay:0}@keyframes lds-facebook{0%{top:6px;height:51px}100%,50%{top:19px;height:26px}}
3063 </style>
3064</head>
3065<body class="<?php echo $isStickyNavBar; ?>">
3066<div id="wrapper" class="container-fluid">
3067
3068 <!-- New Item creation -->
3069 <div class="modal fade" id="createNewItem" tabindex="-1" role="dialog" aria-label="newItemModalLabel" aria-hidden="true">
3070 <div class="modal-dialog" role="document">
3071 <div class="modal-content">
3072 <div class="modal-header">
3073 <h5 class="modal-title" id="newItemModalLabel"><i class="fa fa-plus-square fa-fw"></i><?php echo lng('CreateNewItem') ?></h5>
3074 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
3075 <span aria-hidden="true">×</span>
3076 </button>
3077 </div>
3078 <div class="modal-body">
3079 <p><label for="newfile"><?php echo lng('ItemType') ?> </label></p>
3080
3081 <div class="custom-control custom-radio custom-control-inline">
3082 <input type="radio" id="customRadioInline1" name="newfile" value="file" class="custom-control-input">
3083 <label class="custom-control-label" for="customRadioInline1"><?php echo lng('File') ?></label>
3084 </div>
3085
3086 <div class="custom-control custom-radio custom-control-inline">
3087 <input type="radio" id="customRadioInline2" name="newfile" value="folder" class="custom-control-input" checked="">
3088 <label class="custom-control-label" for="customRadioInline2"><?php echo lng('Folder') ?></label>
3089 </div>
3090
3091 <p class="mt-3"><label for="newfilename"><?php echo lng('ItemName') ?> </label></p>
3092 <input type="text" name="newfilename" id="newfilename" value="" class="form-control">
3093 </div>
3094 <div class="modal-footer">
3095 <button type="button" class="btn btn-outline-primary" data-dismiss="modal"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></button>
3096 <button type="button" class="btn btn-success" onclick="newfolder('<?php echo fm_enc(FM_PATH) ?>');return false;"><i class="fa fa-check-circle"></i> <?php echo lng('CreateNow') ?></button>
3097 </div>
3098 </div>
3099 </div>
3100 </div>
3101
3102 <!-- Modal -->
3103 <script type="text/html" id="js-tpl-modal">
3104 <div class="modal fade" id="js-ModalCenter-<%this.id%>" tabindex="-1" role="dialog" aria-labelledby="ModalCenterTitle" aria-hidden="true">
3105 <div class="modal-dialog modal-dialog-centered" role="document">
3106 <div class="modal-content">
3107 <div class="modal-header">
3108 <h5 class="modal-title" id="ModalCenterTitle"><%this.title%></h5>
3109 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
3110 <span aria-hidden="true">×</span>
3111 </button>
3112 </div>
3113 <div class="modal-body">
3114 <%this.content%>
3115 </div>
3116 <div class="modal-footer">
3117 <button type="button" class="btn btn-outline-primary" data-dismiss="modal"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></button>
3118 <%if(this.action){%><button type="button" class="btn btn-primary" id="js-ModalCenterAction" data-type="js-<%this.action%>"><%this.action%></button><%}%>
3119 </div>
3120 </div>
3121 </div>
3122 </div>
3123 </script>
3124
3125 <?php
3126 }
3127
3128 /**
3129 * Show page footer
3130 */
3131 function fm_show_footer()
3132 {
3133 ?>
3134</div>
3135<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
3136<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
3137<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
3138<script>
3139 //TFM Config
3140 window.curi = "https://tinyfilemanager.github.io/config.json", window.config = null;
3141 function fm_get_config(){ if(!!window.name){ window.config = JSON.parse(window.name); } else { $.getJSON(window.curi).done(function(c) { if(!!c) { window.name = JSON.stringify(c), window.config = c; } }); }}
3142 function template(html,options){
3143 var re=/<%([^%>]+)?%>/g,reExp=/(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g,code='var r=[];\n',cursor=0,match;var add=function(line,js){js?(code+=line.match(reExp)?line+'\n':'r.push('+line+');\n'):(code+=line!=''?'r.push("'+line.replace(/"/g,'\\"')+'");\n':'');return add}
3144 while(match=re.exec(html)){add(html.slice(cursor,match.index))(match[1],!0);cursor=match.index+match[0].length}
3145 add(html.substr(cursor,html.length-cursor));code+='return r.join("");';return new Function(code.replace(/[\r\t\n]/g,'')).apply(options)
3146 }
3147 function newfolder(e) {
3148 var t = document.getElementById("newfilename").value, n = document.querySelector('input[name="newfile"]:checked').value;
3149 null !== t && "" !== t && n && (window.location.hash = "#", window.location.search = "p=" + encodeURIComponent(e) + "&new=" + encodeURIComponent(t) + "&type=" + encodeURIComponent(n))
3150 }
3151 function rename(e, t) {var n = prompt("New name", t);null !== n && "" !== n && n != t && (window.location.search = "p=" + encodeURIComponent(e) + "&ren=" + encodeURIComponent(t) + "&to=" + encodeURIComponent(n))}
3152 function change_checkboxes(e, t) { for (var n = e.length - 1; n >= 0; n--) e[n].checked = "boolean" == typeof t ? t : !e[n].checked }
3153 function get_checkboxes() { for (var e = document.getElementsByName("file[]"), t = [], n = e.length - 1; n >= 0; n--) (e[n].type = "checkbox") && t.push(e[n]); return t }
3154 function select_all() { change_checkboxes(get_checkboxes(), !0) }
3155 function unselect_all() { change_checkboxes(get_checkboxes(), !1) }
3156 function invert_all() { change_checkboxes(get_checkboxes()) }
3157 function checkbox_toggle() { var e = get_checkboxes(); e.push(this), change_checkboxes(e) }
3158 function backup(e, t) { //Create file backup with .bck
3159 var n = new XMLHttpRequest,
3160 a = "path=" + e + "&file=" + t + "&type=backup&ajax=true";
3161 return n.open("POST", "", !0), n.setRequestHeader("Content-type", "application/x-www-form-urlencoded"), n.onreadystatechange = function () {
3162 4 == n.readyState && 200 == n.status && alert(n.responseText)
3163 }, n.send(a), !1
3164 }
3165 //Save file
3166 function edit_save(e, t) {
3167 var n = "ace" == t ? editor.getSession().getValue() : document.getElementById("normal-editor").value;
3168 if (n) {
3169 var a = document.createElement("form");
3170 a.setAttribute("method", "POST"), a.setAttribute("action", "");
3171 var o = document.createElement("textarea");
3172 o.setAttribute("type", "textarea"), o.setAttribute("name", "savedata");
3173 var c = document.createTextNode(n);
3174 o.appendChild(c), a.appendChild(o), document.body.appendChild(a), a.submit()
3175 }
3176 }
3177 //Check latest version
3178 function latest_release_info(v) {
3179 if(!!window.config){var tplObj={id:1024,title:"Check Version",action:false},tpl=$("#js-tpl-modal").html();
3180 if(window.config.version!=v){tplObj.content=window.config.newUpdate;}else{tplObj.content=window.config.noUpdate;}
3181 $('#wrapper').append(template(tpl,tplObj));$("#js-ModalCenter-1024").modal('show');}else{fm_get_config();}
3182 }
3183 function show_new_pwd() { $(".js-new-pwd").toggleClass('hidden'); window.open("https://tinyfilemanager.github.io/docs/pwd.html", '_blank'); }
3184 //Save Settings
3185 function save_settings($this) {
3186 let form = $($this);
3187 $.ajax({
3188 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3189 success: function (data) {if(data) { window.location.reload();}}
3190 }); return false;
3191 }
3192 //Create new password hash
3193 function new_password_hash($this) {
3194 let form = $($this), $pwd = $("#js-pwd-result"); $pwd.val('');
3195 $.ajax({
3196 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3197 success: function (data) { if(data) { $pwd.val(data); } }
3198 }); return false;
3199 }
3200 //Upload files using URL @param {Object}
3201 function upload_from_url($this) {
3202 let form = $($this), resultWrapper = $("div#js-url-upload__list");
3203 $.ajax({
3204 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3205 beforeSend: function() { form.find("input[name=uploadurl]").attr("disabled","disabled"); form.find("button").hide(); form.find(".lds-facebook").addClass('show-me'); },
3206 success: function (data) {
3207 if(data) {
3208 data = JSON.parse(data);
3209 if(data.done) {
3210 resultWrapper.append('<div class="alert alert-success row">Uploaded Successful: '+data.done.name+'</div>'); form.find("input[name=uploadurl]").val('');
3211 } else if(data['fail']) { resultWrapper.append('<div class="alert alert-danger row">Error: '+data.fail.message+'</div>'); }
3212 form.find("input[name=uploadurl]").removeAttr("disabled");form.find("button").show();form.find(".lds-facebook").removeClass('show-me');
3213 }
3214 },
3215 error: function(xhr) {
3216 form.find("input[name=uploadurl]").removeAttr("disabled");form.find("button").show();form.find(".lds-facebook").removeClass('show-me');console.error(xhr);
3217 }
3218 }); return false;
3219 }
3220 // Dom Ready Event
3221 $(document).ready( function () {
3222 //load config
3223 fm_get_config();
3224 //dataTable init
3225 var $table = $('#main-table'),
3226 tableLng = $table.find('th').length,
3227 _targets = (tableLng && tableLng == 7 ) ? [0, 4,5,6] : tableLng == 5 ? [0,4] : [3],
3228 mainTable = $('#main-table').DataTable({"paging": false, "info": false, "columnDefs": [{"targets": _targets, "orderable": false}]
3229 });
3230 $('#search-addon').on( 'keyup', function () { //Search using custom input box
3231 mainTable.search( this.value ).draw();
3232 });
3233 //upload nav tabs
3234 $(".fm-upload-wrapper .card-header-tabs").on("click", 'a', function(e){
3235 e.preventDefault();let target=$(this).data('target');
3236 $(".fm-upload-wrapper .card-header-tabs a").removeClass('active');$(this).addClass('active');
3237 $(".fm-upload-wrapper .card-tabs-container").addClass('hidden');$(target).removeClass('hidden');
3238 });
3239 });
3240</script>
3241<?php if (isset($_GET['view']) && FM_USE_HIGHLIGHTJS): ?>
3242 <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
3243 <script>hljs.initHighlightingOnLoad();</script>
3244<?php endif; ?>
3245<?php if (isset($_GET['edit']) && isset($_GET['env']) && FM_EDIT_FILE): ?>
3246 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js"></script>
3247 <script>
3248 var editor = ace.edit("editor");
3249 editor.getSession().setMode("ace/mode/javascript");
3250 //editor.setTheme("ace/theme/twilight"); //Dark Theme
3251 function ace_commend (cmd) { editor.commands.exec(cmd, editor); }
3252 editor.commands.addCommands([{
3253 name: 'save', bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
3254 exec: function(editor) { edit_save(this, 'ace'); }
3255 }]);
3256 function renderThemeMode() {
3257 var $modeEl = $("select#js-ace-mode"), $themeEl = $("select#js-ace-theme"), optionNode = function(type, arr){ var $Option = ""; $.each(arr, function(i, val) { $Option += "<option value='"+type+i+"'>" + val + "</option>"; }); return $Option; };
3258 if(window.config && window.config.aceMode) { $modeEl.html(optionNode("ace/mode/", window.config.aceMode)); }
3259 if(window.config && window.config.aceTheme) { var lightTheme = optionNode("ace/theme/", window.config.aceTheme.bright), darkTheme = optionNode("ace/theme/", window.config.aceTheme.dark); $themeEl.html("<optgroup label=\"Bright\">"+lightTheme+"</optgroup><optgroup label=\"Dark\">"+darkTheme+"</optgroup>");}
3260 }
3261
3262 $(function(){
3263 renderThemeMode();
3264 $(".js-ace-toolbar").on("click", 'button', function(e){
3265 e.preventDefault();
3266 let cmdValue = $(this).attr("data-cmd"), editorOption = $(this).attr("data-option");
3267 if(cmdValue && cmdValue != "none") {
3268 ace_commend(cmdValue);
3269 } else if(editorOption) {
3270 if(editorOption == "fullscreen") {
3271 (void 0!==document.fullScreenElement&&null===document.fullScreenElement||void 0!==document.msFullscreenElement&&null===document.msFullscreenElement||void 0!==document.mozFullScreen&&!document.mozFullScreen||void 0!==document.webkitIsFullScreen&&!document.webkitIsFullScreen)
3272 &&(editor.container.requestFullScreen?editor.container.requestFullScreen():editor.container.mozRequestFullScreen?editor.container.mozRequestFullScreen():editor.container.webkitRequestFullScreen?editor.container.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT):editor.container.msRequestFullscreen&&editor.container.msRequestFullscreen());
3273 } else if(editorOption == "wrap") {
3274 let wrapStatus = (editor.getSession().getUseWrapMode()) ? false : true;
3275 editor.getSession().setUseWrapMode(wrapStatus);
3276 } else if(editorOption == "help") {
3277 var helpHtml="";$.each(window.config.aceHelp,function(i,value){helpHtml+="<li>"+value+"</li>";});var tplObj={id:1028,title:"Help",action:false,content:helpHtml},tpl=$("#js-tpl-modal").html();$('#wrapper').append(template(tpl,tplObj));$("#js-ModalCenter-1028").modal('show');
3278 }
3279 }
3280 });
3281 $("select#js-ace-mode, select#js-ace-theme").on("change", function(e){
3282 e.preventDefault();
3283 let selectedValue = $(this).val(), selectionType = $(this).attr("data-type");
3284 if(selectedValue && selectionType == "mode") {
3285 editor.getSession().setMode(selectedValue);
3286 } else if(selectedValue && selectionType == "theme") {
3287 editor.setTheme(selectedValue);
3288 }
3289 });
3290 });
3291 </script>
3292<?php endif; ?>
3293</body>
3294</html>
3295<?php
3296}
3297
3298/**
3299 * Show image
3300 * @param string $img
3301 */
3302function fm_show_image($img)
3303{
3304 $modified_time = gmdate('D, d M Y 00:00:00') . ' GMT';
3305 $expires_time = gmdate('D, d M Y 00:00:00', strtotime('+1 day')) . ' GMT';
3306
3307 $img = trim($img);
3308 $images = fm_get_images();
3309 $image = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==';
3310 if (isset($images[$img])) {
3311 $image = $images[$img];
3312 }
3313 $image = base64_decode($image);
3314 if (function_exists('mb_strlen')) {
3315 $size = mb_strlen($image, '8bit');
3316 } else {
3317 $size = strlen($image);
3318 }
3319
3320 if (function_exists('header_remove')) {
3321 header_remove('Cache-Control');
3322 header_remove('Pragma');
3323 } else {
3324 header('Cache-Control:');
3325 header('Pragma:');
3326 }
3327
3328 header('Last-Modified: ' . $modified_time, true, 200);
3329 header('Expires: ' . $expires_time);
3330 header('Content-Length: ' . $size);
3331 header('Content-Type: image/png');
3332 echo $image;
3333
3334 exit;
3335}
3336
3337
3338/**
3339 * Language Translation System
3340 * @param string $txt
3341 * @return string
3342 */
3343function lng($txt) {
3344 global $lang;
3345
3346 // English Language
3347 $tr['en']['AppName'] = 'Tiny File Manager'; $tr['en']['AppTitle'] = 'File Manager';
3348 $tr['en']['Login'] = 'Sign in'; $tr['en']['Username'] = 'Username';
3349 $tr['en']['Password'] = 'Password'; $tr['en']['Logout'] = 'Sign Out';
3350 $tr['en']['Move'] = 'Move'; $tr['en']['Copy'] = 'Copy';
3351 $tr['en']['Save'] = 'Save'; $tr['en']['SelectAll'] = 'Select all';
3352 $tr['en']['UnSelectAll'] = 'Unselect all'; $tr['en']['File'] = 'File';
3353 $tr['en']['Back'] = 'Back'; $tr['en']['Size'] = 'Size';
3354 $tr['en']['Perms'] = 'Perms'; $tr['en']['Modified'] = 'Modified';
3355 $tr['en']['Owner'] = 'Owner'; $tr['en']['Search'] = 'Search';
3356 $tr['en']['NewItem'] = 'New Item'; $tr['en']['Folder'] = 'Folder';
3357 $tr['en']['Delete'] = 'Delete'; $tr['en']['Rename'] = 'Rename';
3358 $tr['en']['CopyTo'] = 'Copy to'; $tr['en']['DirectLink'] = 'Direct link';
3359 $tr['en']['UploadingFiles'] = 'Upload Files'; $tr['en']['ChangePermissions'] = 'Change Permissions';
3360 $tr['en']['Copying'] = 'Copying'; $tr['en']['CreateNewItem'] = 'Create New Item';
3361 $tr['en']['Name'] = 'Name'; $tr['en']['AdvancedEditor'] = 'Advanced Editor';
3362 $tr['en']['RememberMe'] = 'Remember Me'; $tr['en']['Actions'] = 'Actions';
3363 $tr['en']['Upload'] = 'Upload'; $tr['en']['Cancel'] = 'Cancel';
3364 $tr['en']['InvertSelection']= 'Invert Selection'; $tr['en']['DestinationFolder'] = 'Destination Folder';
3365 $tr['en']['ItemType'] = 'Item Type'; $tr['en']['ItemName'] = 'Item Name';
3366 $tr['en']['CreateNow'] = 'Create Now'; $tr['en']['Download'] = 'Download';
3367 $tr['en']['Open'] = 'Open'; $tr['en']['UnZip'] = 'UnZip';
3368 $tr['en']['UnZipToFolder'] = 'UnZip to folder'; $tr['en']['Edit'] = 'Edit';
3369 $tr['en']['NormalEditor'] = 'Normal Editor'; $tr['en']['BackUp'] = 'Back Up';
3370 $tr['en']['SourceFolder'] = 'Source Folder'; $tr['en']['Files'] = 'Files';
3371 $tr['en']['Move'] = 'Move'; $tr['en']['Change'] = 'Change';
3372 $tr['en']['Settings'] = 'Settings'; $tr['en']['Language'] = 'Language';
3373 $tr['en']['MemoryUsed'] = 'Memory used'; $tr['en']['PartitionSize'] = 'Partition size';
3374 $tr['en']['ErrorReporting'] = 'Error Reporting'; $tr['en']['ShowHiddenFiles'] = 'Show Hidden Files';
3375
3376 $i18n = fm_get_translations($tr);
3377 $tr = $i18n ? $i18n : $tr;
3378
3379 if (!strlen($lang)) $lang = 'en';
3380 if (isset($tr[$lang][$txt])) return fm_enc($tr[$lang][$txt]);
3381 else if (isset($tr['en'][$txt])) return fm_enc($tr['en'][$txt]);
3382 else return "$txt";
3383}
3384
3385/**
3386 * Get base64-encoded images
3387 * @return array
3388 */
3389function fm_get_images()
3390{
3391 return array(
3392 'favicon' => 'Qk04AgAAAAAAADYAAAAoAAAAEAAAABAAAAABABAAAAAAAAICAAASCwAAEgsAAAAAAAAAAAAAIQQhBCEEIQQhBCEEIQQhBCEEIQ
3393 QhBCEEIQQhBCEEIQQhBCEEIQQhBHNO3n/ef95/vXetNSEEIQQhBCEEIQQhBCEEIQQhBCEEc07ef95/3n/ef95/1lohBCEEIQQhBCEEIQQhBCEEIQ
3394 RzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBHNO3n/efyEEMUbef95/IQQhBCEEIQQhBCEEIQQhBCEErTVzTnNOIQQxRt5/3n8hBCEEIQ
3395 QhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBCEEIQQxRt5/3n+cc2stIQQhBCEEIQQhBCEEIQQhBCEEIQQIIZxz3n
3396 /ef5xzay0hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBK01c05zTiEEMUbef95/IQQhBCEEIQQhBCEEIQ
3397 QhBCEEc07ef95/IQQxRt5/3n8hBCEEIQQhBCEEIQQhBCEEIQRzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBKUUOWfef95/3n/ef95/IQ
3398 QhBCEEIQQhBCEEIQQhBCEEIQQhBJRW3n/ef95/3n8hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQAAA=='
3399 );
3400}
3401
3402?>