· 5 years ago · Mar 12, 2020, 10:00 AM
1<?php
2//Default Configuration
3$CONFIG = '{"lang":"en","error_reporting":false,"show_hidden":false,"hide_Cols":false,"calc_folder":false}';
4
5/**
6 * H3K | Tiny File Manager V2.4.1
7 * CCP Programmers | ccpprogrammers@gmail.com
8 * https://tinyfilemanager.github.io
9 */
10
11//TFM version
12define('VERSION', '2.4.1');
13
14//Application Title
15define('APP_TITLE', 'Tiny File Manager');
16
17// --- EDIT BELOW CONFIGURATION CAREFULLY ---
18
19
20// Auth with login/password
21// set true/false to enable/disable it
22// Is independent from IP white- and blacklisting
23$use_auth = true;
24
25// Login user name and password
26// Users: array('Username' => 'Password', 'Username2' => 'Password2', ...)
27// Generate secure password hash - https://tinyfilemanager.github.io/docs/pwd.html
28$auth_users = array(
29 'admin' => '$2y$10$/K.hjNr84lLNDt8fTXjoI.DBp6PpeyoJ.mGwrrLuCZfAwfSAGqhOW', //admin@123
30 'user' => '$2y$10$Fg6Dz8oH9fPoZ2jJan5tZuv6Z4Kp7avtQ9bDfrdRntXtPeiMAZyGO' //12345
31);
32
33// Readonly users
34// e.g. array('users', 'guest', ...)
35$readonly_users = array(
36 'user'
37);
38
39// user specific directories
40// array('Username' => 'Directory path', 'Username2' => 'Directory path', ...)
41$directories_users = array();
42
43// Enable highlight.js (https://highlightjs.org/) on view's page
44$use_highlightjs = true;
45
46// highlight.js style
47$highlightjs_style = 'vs';
48
49// Enable ace.js (https://ace.c9.io/) on view's page
50$edit_files = true;
51
52// Default timezone for date() and time()
53// Doc - http://php.net/manual/en/timezones.php
54$default_timezone = 'Etc/UTC'; // UTC
55
56// Root path for file manager
57// use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder'
58$root_path = $_SERVER['DOCUMENT_ROOT'];
59
60// Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder'
61// Will not working if $root_path will be outside of server document root
62$root_url = '';
63
64// Server hostname. Can set manually if wrong
65$http_host = $_SERVER['HTTP_HOST'];
66
67// input encoding for iconv
68$iconv_input_encoding = 'UTF-8';
69
70// date() format for file modification date
71// Doc - https://www.php.net/manual/en/function.date.php
72$datetime_format = 'd.m.y H:i';
73
74// Allowed file extensions for create and rename files
75// e.g. 'txt,html,css,js'
76$allowed_file_extensions = '';
77
78// Allowed file extensions for upload files
79// e.g. 'gif,png,jpg,html,txt'
80$allowed_upload_extensions = '';
81
82// Favicon path. This can be either a full url to an .PNG image, or a path based on the document root.
83// full path, e.g http://example.com/favicon.png
84// local path, e.g images/icons/favicon.png
85$favicon_path = '?img=favicon';
86
87// Files and folders to excluded from listing
88// e.g. array('myfile.html', 'personal-folder', '*.php', ...)
89$exclude_items = array();
90
91// Online office Docs Viewer
92// Availabe rules are 'google', 'microsoft' or false
93// google => View documents using Google Docs Viewer
94// microsoft => View documents using Microsoft Web Apps Viewer
95// false => disable online doc viewer
96$online_viewer = 'google';
97
98// Sticky Nav bar
99// true => enable sticky header
100// false => disable sticky header
101$sticky_navbar = true;
102
103// Maximum file upload size
104// Increase the following values in php.ini to work properly
105// memory_limit, upload_max_filesize, post_max_size
106define('MAX_UPLOAD_SIZE', '2048');
107
108// Possible rules are 'OFF', 'AND' or 'OR'
109// OFF => Don't check connection IP, defaults to OFF
110// AND => Connection must be on the whitelist, and not on the blacklist
111// OR => Connection must be on the whitelist, or not on the blacklist
112$ip_ruleset = 'OFF';
113
114// Should users be notified of their block?
115$ip_silent = true;
116
117// IP-addresses, both ipv4 and ipv6
118$ip_whitelist = array(
119 '127.0.0.1', // local ipv4
120 '::1' // local ipv6
121);
122
123// IP-addresses, both ipv4 and ipv6
124$ip_blacklist = array(
125 '0.0.0.0', // non-routable meta ipv4
126 '::' // non-routable meta ipv6
127);
128
129// --- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL ---
130
131// private key and session name to store to the session
132if ( !defined( 'FM_SESSION_ID')) {
133 define('FM_SESSION_ID', 'filemanager');
134}
135
136// Configuration
137$cfg = new FM_Config();
138
139// Default language
140$lang = isset($cfg->data['lang']) ? $cfg->data['lang'] : 'en';
141
142// Show or hide files and folders that starts with a dot
143$show_hidden_files = isset($cfg->data['show_hidden']) ? $cfg->data['show_hidden'] : true;
144
145// PHP error reporting - false = Turns off Errors, true = Turns on Errors
146$report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_reporting'] : true;
147
148// Hide Permissions and Owner cols in file-listing
149$hide_Cols = isset($cfg->data['hide_Cols']) ? $cfg->data['hide_Cols'] : true;
150
151// Show Dirsize: true or speedup output: false
152$calc_folder = isset($cfg->data['calc_folder']) ? $cfg->data['calc_folder'] : true;
153
154//available languages
155$lang_list = array(
156 'en' => 'English'
157);
158
159if ($report_errors == true) {
160 @ini_set('error_reporting', E_ALL);
161 @ini_set('display_errors', 1);
162} else {
163 @ini_set('error_reporting', E_ALL);
164 @ini_set('display_errors', 0);
165}
166
167// if fm included
168if (defined('FM_EMBED')) {
169 $use_auth = false;
170 $sticky_navbar = false;
171} else {
172 @set_time_limit(600);
173
174 date_default_timezone_set($default_timezone);
175
176 ini_set('default_charset', 'UTF-8');
177 if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) {
178 mb_internal_encoding('UTF-8');
179 }
180 if (function_exists('mb_regex_encoding')) {
181 mb_regex_encoding('UTF-8');
182 }
183
184 session_cache_limiter('');
185 session_name(FM_SESSION_ID );
186 @session_start();
187}
188
189if (empty($auth_users)) {
190 $use_auth = false;
191}
192
193$is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1)
194 || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
195
196// update $root_url based on user specific directories
197if (isset($_SESSION[FM_SESSION_ID]['logged']) && !empty($directories_users[$_SESSION[FM_SESSION_ID]['logged']])) {
198 $wd = fm_clean_path(dirname($_SERVER['PHP_SELF']));
199 $root_url = $root_url.$wd.DIRECTORY_SEPARATOR.$directories_users[$_SESSION[FM_SESSION_ID]['logged']];
200}
201// clean $root_url
202$root_url = fm_clean_path($root_url);
203
204// abs path for site
205defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : ''));
206defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']);
207
208// logout
209if (isset($_GET['logout'])) {
210 unset($_SESSION[FM_SESSION_ID]['logged']);
211 fm_redirect(FM_SELF_URL);
212}
213
214// Show image here
215if (isset($_GET['img'])) {
216 fm_show_image($_GET['img']);
217}
218
219// Validate connection IP
220if($ip_ruleset != 'OFF'){
221 $clientIp = $_SERVER['REMOTE_ADDR'];
222
223 $proceed = false;
224
225 $whitelisted = in_array($clientIp, $ip_whitelist);
226 $blacklisted = in_array($clientIp, $ip_blacklist);
227
228 if($ip_ruleset == 'AND'){
229 if($whitelisted == true && $blacklisted == false){
230 $proceed = true;
231 }
232 } else
233 if($ip_ruleset == 'OR'){
234 if($whitelisted == true || $blacklisted == false){
235 $proceed = true;
236 }
237 }
238
239 if($proceed == false){
240 trigger_error('User connection denied from: ' . $clientIp, E_USER_WARNING);
241
242 if($ip_silent == false){
243 fm_set_msg('Access denied. IP restriction applicable', 'error');
244 fm_show_header_login();
245 fm_show_message();
246 }
247
248 exit();
249 }
250}
251
252// Auth
253if ($use_auth) {
254 if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) {
255 // Logged
256 } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'])) {
257 // Logging In
258 sleep(1);
259 if(function_exists('password_verify')) {
260 if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']])) {
261 $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr'];
262 fm_set_msg('You are logged in');
263 fm_redirect(FM_SELF_URL . '?p=');
264 } else {
265 unset($_SESSION[FM_SESSION_ID]['logged']);
266 fm_set_msg('Login failed. Invalid username or password', 'error');
267 fm_redirect(FM_SELF_URL);
268 }
269 } else {
270 fm_set_msg('password_hash not supported, Upgrade PHP version', 'error');;
271 }
272 } else {
273 // Form
274 unset($_SESSION[FM_SESSION_ID]['logged']);
275 fm_show_header_login();
276 ?>
277 <section class="h-100">
278 <div class="container h-100">
279 <div class="row justify-content-md-center h-100">
280 <div class="card-wrapper">
281 <div class="card fat">
282 <div class="card-body">
283 <form class="form-signin" action="" method="post" autocomplete="off">
284 <div class="form-group">
285 <div class="brand">
286 <svg version="1.0" xmlns="http://www.w3.org/2000/svg" M1008 width="100%" height="80px" viewBox="0 0 238.000000 140.000000" aria-label="H3K Tiny File Manager">
287 <g transform="translate(0.000000,140.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none">
288 <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"/>
289 <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"/>
290 <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>
291 </svg>
292 </div>
293 <div class="text-center">
294 <h1 class="card-title"><?php echo APP_TITLE; ?></h1>
295 </div>
296 </div>
297 <hr />
298 <div class="form-group">
299 <label for="fm_usr"><?php echo lng('Username'); ?></label>
300 <input type="text" class="form-control" id="fm_usr" name="fm_usr" required autofocus>
301 </div>
302
303 <div class="form-group">
304 <label for="fm_pwd"><?php echo lng('Password'); ?></label>
305 <input type="password" class="form-control" id="fm_pwd" name="fm_pwd" required>
306 </div>
307
308 <div class="form-group">
309 <?php fm_show_message(); ?>
310 </div>
311
312 <div class="form-group">
313 <button type="submit" class="btn btn-success btn-block mt-4" role="button">
314 <?php echo lng('Login'); ?>
315 </button>
316 </div>
317 </form>
318 </div>
319 </div>
320 <div class="footer text-center">
321 —— ©
322 <a href="https://tinyfilemanager.github.io/" target="_blank" class="text-muted" data-version="<?php echo VERSION; ?>">CCP Programmers</a> ——
323 </div>
324 </div>
325 </div>
326 </div>
327 </section>
328
329 <?php
330 fm_show_footer_login();
331 exit;
332 }
333}
334
335// update root path
336if ($use_auth && isset($_SESSION[FM_SESSION_ID]['logged'])) {
337 $root_path = isset($directories_users[$_SESSION[FM_SESSION_ID]['logged']]) ? $directories_users[$_SESSION[FM_SESSION_ID]['logged']] : $root_path;
338}
339
340// clean and check $root_path
341$root_path = rtrim($root_path, '\\/');
342$root_path = str_replace('\\', '/', $root_path);
343if (!@is_dir($root_path)) {
344 echo "<h1>Root path \"{$root_path}\" not found!</h1>";
345 exit;
346}
347
348defined('FM_SHOW_HIDDEN') || define('FM_SHOW_HIDDEN', $show_hidden_files);
349defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path);
350defined('FM_LANG') || define('FM_LANG', $lang);
351defined('FM_FILE_EXTENSION') || define('FM_FILE_EXTENSION', $allowed_file_extensions);
352defined('FM_UPLOAD_EXTENSION') || define('FM_UPLOAD_EXTENSION', $allowed_upload_extensions);
353defined('FM_EXCLUDE_ITEMS') || define('FM_EXCLUDE_ITEMS', $exclude_items);
354defined('FM_DOC_VIEWER') || define('FM_DOC_VIEWER', $online_viewer);
355define('FM_READONLY', $use_auth && !empty($readonly_users) && isset($_SESSION[FM_SESSION_ID]['logged']) && in_array($_SESSION[FM_SESSION_ID]['logged'], $readonly_users));
356define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\');
357
358// always use ?p=
359if (!isset($_GET['p']) && empty($_FILES)) {
360 fm_redirect(FM_SELF_URL . '?p=');
361}
362
363// get path
364$p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : '');
365
366// clean path
367$p = fm_clean_path($p);
368
369// for ajax request - save
370$input = file_get_contents('php://input');
371$_POST = (strpos($input, 'ajax') != FALSE && strpos($input, 'save') != FALSE) ? json_decode($input, true) : $_POST;
372
373// instead globals vars
374define('FM_PATH', $p);
375define('FM_USE_AUTH', $use_auth);
376define('FM_EDIT_FILE', $edit_files);
377defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding);
378defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs);
379defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style);
380defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format);
381
382unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style);
383
384/*************************** ACTIONS ***************************/
385
386// AJAX Request
387if (isset($_POST['ajax']) && !FM_READONLY) {
388
389 // save
390 if (isset($_POST['type']) && $_POST['type'] == "save") {
391 // get current path
392 $path = FM_ROOT_PATH;
393 if (FM_PATH != '') {
394 $path .= '/' . FM_PATH;
395 }
396 // check path
397 if (!is_dir($path)) {
398 fm_redirect(FM_SELF_URL . '?p=');
399 }
400 $file = $_GET['edit'];
401 $file = fm_clean_path($file);
402 $file = str_replace('/', '', $file);
403 if ($file == '' || !is_file($path . '/' . $file)) {
404 fm_set_msg('File not found', 'error');
405 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
406 }
407 header('X-XSS-Protection:0');
408 $file_path = $path . '/' . $file;
409
410 $writedata = $_POST['content'];
411 $fd = fopen($file_path, "w");
412 @fwrite($fd, $writedata);
413 fclose($fd);
414 die(true);
415 }
416
417 //search : get list of files from the current folder
418 if(isset($_POST['type']) && $_POST['type']=="search") {
419 $dir = FM_ROOT_PATH;
420 $response = scan($_POST['path'], $_POST['content']);
421 echo json_encode($response);
422 exit();
423 }
424
425 // backup files
426 if (isset($_POST['type']) && $_POST['type'] == "backup") {
427 $file = $_POST['file'];
428 $path = $_POST['path'];
429 $date = date("dMy-His");
430 $newFile = $file . '-' . $date . '.bak';
431 copy($path . '/' . $file, $path . '/' . $newFile) or die("Unable to backup");
432 echo "Backup $newFile Created";
433 }
434
435 // Save Config
436 if (isset($_POST['type']) && $_POST['type'] == "settings") {
437 global $cfg, $lang, $report_errors, $show_hidden_files, $lang_list, $hide_Cols, $calc_folder;
438 $newLng = $_POST['js-language'];
439 fm_get_translations([]);
440 if (!array_key_exists($newLng, $lang_list)) {
441 $newLng = 'en';
442 }
443
444 $erp = isset($_POST['js-error-report']) && $_POST['js-error-report'] == "true" ? true : false;
445 $shf = isset($_POST['js-show-hidden']) && $_POST['js-show-hidden'] == "true" ? true : false;
446 $hco = isset($_POST['js-hide-cols']) && $_POST['js-hide-cols'] == "true" ? true : false;
447 $caf = isset($_POST['js-calc-folder']) && $_POST['js-calc-folder'] == "true" ? true : false;
448
449 if ($cfg->data['lang'] != $newLng) {
450 $cfg->data['lang'] = $newLng;
451 $lang = $newLng;
452 }
453 if ($cfg->data['error_reporting'] != $erp) {
454 $cfg->data['error_reporting'] = $erp;
455 $report_errors = $erp;
456 }
457 if ($cfg->data['show_hidden'] != $shf) {
458 $cfg->data['show_hidden'] = $shf;
459 $show_hidden_files = $shf;
460 }
461 if ($cfg->data['show_hidden'] != $shf) {
462 $cfg->data['show_hidden'] = $shf;
463 $show_hidden_files = $shf;
464 }
465 if ($cfg->data['hide_Cols'] != $hco) {
466 $cfg->data['hide_Cols'] = $hco;
467 $hide_Cols = $hco;
468 }
469 if ($cfg->data['calc_folder'] != $caf) {
470 $cfg->data['calc_folder'] = $caf;
471 $calc_folder = $caf;
472 }
473 $cfg->save();
474 echo true;
475 }
476
477 // new password hash
478 if (isset($_POST['type']) && $_POST['type'] == "pwdhash") {
479 $res = isset($_POST['inputPassword2']) && !empty($_POST['inputPassword2']) ? password_hash($_POST['inputPassword2'], PASSWORD_DEFAULT) : '';
480 echo $res;
481 }
482
483 //upload using url
484 if(isset($_POST['type']) && $_POST['type'] == "upload" && !empty($_REQUEST["uploadurl"])) {
485 $path = FM_ROOT_PATH;
486 if (FM_PATH != '') {
487 $path .= '/' . FM_PATH;
488 }
489
490 $url = !empty($_REQUEST["uploadurl"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["uploadurl"])) ? stripslashes($_REQUEST["uploadurl"]) : null;
491 $use_curl = false;
492 $temp_file = tempnam(sys_get_temp_dir(), "upload-");
493 $fileinfo = new stdClass();
494 $fileinfo->name = trim(basename($url), ".\x00..\x20");
495
496 $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false;
497 $ext = strtolower(pathinfo($fileinfo->name, PATHINFO_EXTENSION));
498 $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;
499
500 function event_callback ($message) {
501 global $callback;
502 echo json_encode($message);
503 }
504
505 function get_file_path () {
506 global $path, $fileinfo, $temp_file;
507 return $path."/".basename($fileinfo->name);
508 }
509
510 $err = false;
511
512 if(!$isFileAllowed) {
513 $err = array("message" => "File extension is not allowed");
514 event_callback(array("fail" => $err));
515 exit();
516 }
517
518 if (!$url) {
519 $success = false;
520 } else if ($use_curl) {
521 @$fp = fopen($temp_file, "w");
522 @$ch = curl_init($url);
523 curl_setopt($ch, CURLOPT_NOPROGRESS, false );
524 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
525 curl_setopt($ch, CURLOPT_FILE, $fp);
526 @$success = curl_exec($ch);
527 $curl_info = curl_getinfo($ch);
528 if (!$success) {
529 $err = array("message" => curl_error($ch));
530 }
531 @curl_close($ch);
532 fclose($fp);
533 $fileinfo->size = $curl_info["size_download"];
534 $fileinfo->type = $curl_info["content_type"];
535 } else {
536 $ctx = stream_context_create();
537 @$success = copy($url, $temp_file, $ctx);
538 if (!$success) {
539 $err = error_get_last();
540 }
541 }
542
543 if ($success) {
544 $success = rename($temp_file, get_file_path());
545 }
546
547 if ($success) {
548 event_callback(array("done" => $fileinfo));
549 } else {
550 unlink($temp_file);
551 if (!$err) {
552 $err = array("message" => "Invalid url parameter");
553 }
554 event_callback(array("fail" => $err));
555 }
556 }
557
558 exit();
559}
560
561// Delete file / folder
562if (isset($_GET['del']) && !FM_READONLY) {
563 $del = str_replace( '/', '', fm_clean_path( $_GET['del'] ) );
564 if ($del != '' && $del != '..' && $del != '.') {
565 $path = FM_ROOT_PATH;
566 if (FM_PATH != '') {
567 $path .= '/' . FM_PATH;
568 }
569 $is_dir = is_dir($path . '/' . $del);
570 if (fm_rdelete($path . '/' . $del)) {
571 $msg = $is_dir ? 'Folder <b>%s</b> deleted' : 'File <b>%s</b> deleted';
572 fm_set_msg(sprintf($msg, fm_enc($del)));
573 } else {
574 $msg = $is_dir ? 'Folder <b>%s</b> not deleted' : 'File <b>%s</b> not deleted';
575 fm_set_msg(sprintf($msg, fm_enc($del)), 'error');
576 }
577 } else {
578 fm_set_msg('Invalid file or folder name', 'error');
579 }
580 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
581}
582
583// Create folder
584if (isset($_GET['new']) && isset($_GET['type']) && !FM_READONLY) {
585 $type = $_GET['type'];
586 $new = str_replace( '/', '', fm_clean_path( strip_tags( $_GET['new'] ) ) );
587 if (fm_isvalid_filename($new) && $new != '' && $new != '..' && $new != '.') {
588 $path = FM_ROOT_PATH;
589 if (FM_PATH != '') {
590 $path .= '/' . FM_PATH;
591 }
592 if ($_GET['type'] == "file") {
593 if (!file_exists($path . '/' . $new)) {
594 if(fm_is_valid_ext($new)) {
595 @fopen($path . '/' . $new, 'w') or die('Cannot open file: ' . $new);
596 fm_set_msg(sprintf('File <b>%s</b> created', fm_enc($new)));
597 } else {
598 fm_set_msg('File extension is not allowed', 'error');
599 }
600 } else {
601 fm_set_msg(sprintf('File <b>%s</b> already exists', fm_enc($new)), 'alert');
602 }
603 } else {
604 if (fm_mkdir($path . '/' . $new, false) === true) {
605 fm_set_msg(sprintf('Folder <b>%s</b> created', $new));
606 } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) {
607 fm_set_msg(sprintf('Folder <b>%s</b> already exists', fm_enc($new)), 'alert');
608 } else {
609 fm_set_msg(sprintf('Folder <b>%s</b> not created', fm_enc($new)), 'error');
610 }
611 }
612 } else {
613 fm_set_msg('Invalid characters in file or folder name', 'error');
614 }
615 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
616}
617
618// Copy folder / file
619if (isset($_GET['copy'], $_GET['finish']) && !FM_READONLY) {
620 // from
621 $copy = $_GET['copy'];
622 $copy = fm_clean_path($copy);
623 // empty path
624 if ($copy == '') {
625 fm_set_msg('Source path not defined', 'error');
626 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
627 }
628 // abs path from
629 $from = FM_ROOT_PATH . '/' . $copy;
630 // abs path to
631 $dest = FM_ROOT_PATH;
632 if (FM_PATH != '') {
633 $dest .= '/' . FM_PATH;
634 }
635 $dest .= '/' . basename($from);
636 // move?
637 $move = isset($_GET['move']);
638 // copy/move
639 if ($from != $dest) {
640 $msg_from = trim(FM_PATH . '/' . basename($from), '/');
641 if ($move) {
642 $rename = fm_rename($from, $dest);
643 if ($rename) {
644 fm_set_msg(sprintf('Moved from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
645 } elseif ($rename === null) {
646 fm_set_msg('File or folder with this path already exists', 'alert');
647 } else {
648 fm_set_msg(sprintf('Error while moving from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
649 }
650 } else {
651 if (fm_rcopy($from, $dest)) {
652 fm_set_msg(sprintf('Copied from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)));
653 } else {
654 fm_set_msg(sprintf('Error while copying from <b>%s</b> to <b>%s</b>', fm_enc($copy), fm_enc($msg_from)), 'error');
655 }
656 }
657 } else {
658 fm_set_msg('Paths must be not equal', 'alert');
659 }
660 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
661}
662
663// Mass copy files/ folders
664if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish']) && !FM_READONLY) {
665 // from
666 $path = FM_ROOT_PATH;
667 if (FM_PATH != '') {
668 $path .= '/' . FM_PATH;
669 }
670 // to
671 $copy_to_path = FM_ROOT_PATH;
672 $copy_to = fm_clean_path($_POST['copy_to']);
673 if ($copy_to != '') {
674 $copy_to_path .= '/' . $copy_to;
675 }
676 if ($path == $copy_to_path) {
677 fm_set_msg('Paths must be not equal', 'alert');
678 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
679 }
680 if (!is_dir($copy_to_path)) {
681 if (!fm_mkdir($copy_to_path, true)) {
682 fm_set_msg('Unable to create destination folder', 'error');
683 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
684 }
685 }
686 // move?
687 $move = isset($_POST['move']);
688 // copy/move
689 $errors = 0;
690 $files = $_POST['file'];
691 if (is_array($files) && count($files)) {
692 foreach ($files as $f) {
693 if ($f != '') {
694 // abs path from
695 $from = $path . '/' . $f;
696 // abs path to
697 $dest = $copy_to_path . '/' . $f;
698 // do
699 if ($move) {
700 $rename = fm_rename($from, $dest);
701 if ($rename === false) {
702 $errors++;
703 }
704 } else {
705 if (!fm_rcopy($from, $dest)) {
706 $errors++;
707 }
708 }
709 }
710 }
711 if ($errors == 0) {
712 $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied';
713 fm_set_msg($msg);
714 } else {
715 $msg = $move ? 'Error while moving items' : 'Error while copying items';
716 fm_set_msg($msg, 'error');
717 }
718 } else {
719 fm_set_msg('Nothing selected', 'alert');
720 }
721 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
722}
723
724// Rename
725if (isset($_GET['ren'], $_GET['to']) && !FM_READONLY) {
726 // old name
727 $old = $_GET['ren'];
728 $old = fm_clean_path($old);
729 $old = str_replace('/', '', $old);
730 // new name
731 $new = $_GET['to'];
732 $new = fm_clean_path(strip_tags($new));
733 $new = str_replace('/', '', $new);
734 // path
735 $path = FM_ROOT_PATH;
736 if (FM_PATH != '') {
737 $path .= '/' . FM_PATH;
738 }
739 // rename
740 if (fm_isvalid_filename($new) && $old != '' && $new != '') {
741 if (fm_rename($path . '/' . $old, $path . '/' . $new)) {
742 fm_set_msg(sprintf('Renamed from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)));
743 } else {
744 fm_set_msg(sprintf('Error while renaming from <b>%s</b> to <b>%s</b>', fm_enc($old), fm_enc($new)), 'error');
745 }
746 } else {
747 fm_set_msg('Invalid characters in file name', 'error');
748 }
749 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
750}
751
752// Download
753if (isset($_GET['dl'])) {
754 $dl = $_GET['dl'];
755 $dl = fm_clean_path($dl);
756 $dl = str_replace('/', '', $dl);
757 $path = FM_ROOT_PATH;
758 if (FM_PATH != '') {
759 $path .= '/' . FM_PATH;
760 }
761 if ($dl != '' && is_file($path . '/' . $dl)) {
762 header('Content-Description: File Transfer');
763 header('Content-Type: application/octet-stream');
764 header('Content-Disposition: attachment; filename="' . basename($path . '/' . $dl) . '"');
765 header('Content-Transfer-Encoding: binary');
766 header('Connection: Keep-Alive');
767 header('Expires: 0');
768 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
769 header('Pragma: public');
770 header('Content-Length: ' . filesize($path . '/' . $dl));
771 ob_end_clean();
772 readfile($path . '/' . $dl);
773 exit;
774 } else {
775 fm_set_msg('File not found', 'error');
776 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
777 }
778}
779
780// Upload
781if (!empty($_FILES) && !FM_READONLY) {
782 $override_file_name = false;
783 $f = $_FILES;
784 $path = FM_ROOT_PATH;
785 $ds = DIRECTORY_SEPARATOR;
786 if (FM_PATH != '') {
787 $path .= '/' . FM_PATH;
788 }
789
790 $errors = 0;
791 $uploads = 0;
792 $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false;
793
794 $filename = $f['file']['name'];
795 $tmp_name = $f['file']['tmp_name'];
796 $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
797 $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;
798
799 $targetPath = $path . $ds;
800 if ( is_writable($targetPath) ) {
801 $fullPath = $path . '/' . $_REQUEST['fullpath'];
802 $folder = substr($fullPath, 0, strrpos($fullPath, "/"));
803
804 if(file_exists ($fullPath) && !$override_file_name) {
805 $ext_1 = $ext ? '.'.$ext : '';
806 $fullPath = str_replace($ext_1, '', $fullPath) .'_'. date('ymdHis'). $ext_1;
807 }
808
809 if (!is_dir($folder)) {
810 $old = umask(0);
811 mkdir($folder, 0777, true);
812 umask($old);
813 }
814
815 if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) {
816 if (move_uploaded_file($tmp_name, $fullPath)) {
817 // Be sure that the file has been uploaded
818 if ( file_exists($fullPath) ) {
819 $response = array (
820 'status' => 'success',
821 'info' => "file upload successful"
822 );
823 } else {
824 $response = array (
825 'status' => 'error',
826 'info' => 'Couldn\'t upload the requested file.'
827 );
828 }
829 } else {
830 $response = array (
831 'status' => 'error',
832 'info' => "Error while uploading files. Uploaded files $uploads",
833 );
834 }
835 }
836 } else {
837 $response = array (
838 'status' => 'error',
839 'info' => 'The specified folder for upload isn\'t writeable.'
840 );
841 }
842 // Return the response
843 echo json_encode($response);
844 exit();
845}
846
847// Mass deleting
848if (isset($_POST['group'], $_POST['delete']) && !FM_READONLY) {
849 $path = FM_ROOT_PATH;
850 if (FM_PATH != '') {
851 $path .= '/' . FM_PATH;
852 }
853
854 $errors = 0;
855 $files = $_POST['file'];
856 if (is_array($files) && count($files)) {
857 foreach ($files as $f) {
858 if ($f != '') {
859 $new_path = $path . '/' . $f;
860 if (!fm_rdelete($new_path)) {
861 $errors++;
862 }
863 }
864 }
865 if ($errors == 0) {
866 fm_set_msg('Selected files and folder deleted');
867 } else {
868 fm_set_msg('Error while deleting items', 'error');
869 }
870 } else {
871 fm_set_msg('Nothing selected', 'alert');
872 }
873
874 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
875}
876
877// Pack files
878if (isset($_POST['group']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) {
879 $path = FM_ROOT_PATH;
880 $ext = 'zip';
881 if (FM_PATH != '') {
882 $path .= '/' . FM_PATH;
883 }
884
885 //set pack type
886 $ext = isset($_POST['tar']) ? 'tar' : 'zip';
887
888
889 if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
890 fm_set_msg('Operations with archives are not available', 'error');
891 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
892 }
893
894 $files = $_POST['file'];
895 if (!empty($files)) {
896 chdir($path);
897
898 if (count($files) == 1) {
899 $one_file = reset($files);
900 $one_file = basename($one_file);
901 $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext;
902 } else {
903 $zipname = 'archive_' . date('ymd_His') . '.'.$ext;
904 }
905
906 if($ext == 'zip') {
907 $zipper = new FM_Zipper();
908 $res = $zipper->create($zipname, $files);
909 } elseif ($ext == 'tar') {
910 $tar = new FM_Zipper_Tar();
911 $res = $tar->create($zipname, $files);
912 }
913
914 if ($res) {
915 fm_set_msg(sprintf('Archive <b>%s</b> created', fm_enc($zipname)));
916 } else {
917 fm_set_msg('Archive not created', 'error');
918 }
919 } else {
920 fm_set_msg('Nothing selected', 'alert');
921 }
922
923 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
924}
925
926// Unpack
927if (isset($_GET['unzip']) && !FM_READONLY) {
928 $unzip = $_GET['unzip'];
929 $unzip = fm_clean_path($unzip);
930 $unzip = str_replace('/', '', $unzip);
931 $isValid = false;
932
933 $path = FM_ROOT_PATH;
934 if (FM_PATH != '') {
935 $path .= '/' . FM_PATH;
936 }
937
938 if ($unzip != '' && is_file($path . '/' . $unzip)) {
939 $zip_path = $path . '/' . $unzip;
940 $ext = pathinfo($zip_path, PATHINFO_EXTENSION);
941 $isValid = true;
942 } else {
943 fm_set_msg('File not found', 'error');
944 }
945
946
947 if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
948 fm_set_msg('Operations with archives are not available', 'error');
949 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
950 }
951
952 if ($isValid) {
953 //to folder
954 $tofolder = '';
955 if (isset($_GET['tofolder'])) {
956 $tofolder = pathinfo($zip_path, PATHINFO_FILENAME);
957 if (fm_mkdir($path . '/' . $tofolder, true)) {
958 $path .= '/' . $tofolder;
959 }
960 }
961
962 if($ext == "zip") {
963 $zipper = new FM_Zipper();
964 $res = $zipper->unzip($zip_path, $path);
965 } elseif ($ext == "tar") {
966 $gzipper = new PharData($zip_path);
967 $res = $gzipper->extractTo($path);
968 }
969
970 if ($res) {
971 fm_set_msg('Archive unpacked');
972 } else {
973 fm_set_msg('Archive not unpacked', 'error');
974 }
975
976 } else {
977 fm_set_msg('File not found', 'error');
978 }
979 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
980}
981
982// Change Perms (not for Windows)
983if (isset($_POST['chmod']) && !FM_READONLY && !FM_IS_WIN) {
984 $path = FM_ROOT_PATH;
985 if (FM_PATH != '') {
986 $path .= '/' . FM_PATH;
987 }
988
989 $file = $_POST['chmod'];
990 $file = fm_clean_path($file);
991 $file = str_replace('/', '', $file);
992 if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
993 fm_set_msg('File not found', 'error');
994 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
995 }
996
997 $mode = 0;
998 if (!empty($_POST['ur'])) {
999 $mode |= 0400;
1000 }
1001 if (!empty($_POST['uw'])) {
1002 $mode |= 0200;
1003 }
1004 if (!empty($_POST['ux'])) {
1005 $mode |= 0100;
1006 }
1007 if (!empty($_POST['gr'])) {
1008 $mode |= 0040;
1009 }
1010 if (!empty($_POST['gw'])) {
1011 $mode |= 0020;
1012 }
1013 if (!empty($_POST['gx'])) {
1014 $mode |= 0010;
1015 }
1016 if (!empty($_POST['or'])) {
1017 $mode |= 0004;
1018 }
1019 if (!empty($_POST['ow'])) {
1020 $mode |= 0002;
1021 }
1022 if (!empty($_POST['ox'])) {
1023 $mode |= 0001;
1024 }
1025
1026 if (@chmod($path . '/' . $file, $mode)) {
1027 fm_set_msg('Permissions changed');
1028 } else {
1029 fm_set_msg('Permissions not changed', 'error');
1030 }
1031
1032 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1033}
1034
1035/*************************** /ACTIONS ***************************/
1036
1037// get current path
1038$path = FM_ROOT_PATH;
1039if (FM_PATH != '') {
1040 $path .= '/' . FM_PATH;
1041}
1042
1043// check path
1044if (!is_dir($path)) {
1045 fm_redirect(FM_SELF_URL . '?p=');
1046}
1047
1048// get parent folder
1049$parent = fm_get_parent_path(FM_PATH);
1050
1051$objects = is_readable($path) ? scandir($path) : array();
1052$folders = array();
1053$files = array();
1054$current_path = array_slice(explode("/",$path), -1)[0];
1055if (is_array($objects) && fm_is_exclude_items($current_path)) {
1056 foreach ($objects as $file) {
1057 if ($file == '.' || $file == '..') {
1058 continue;
1059 }
1060 if (!FM_SHOW_HIDDEN && substr($file, 0, 1) === '.') {
1061 continue;
1062 }
1063 $new_path = $path . '/' . $file;
1064 if (@is_file($new_path) && fm_is_exclude_items($file)) {
1065 $files[] = $file;
1066 } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) {
1067 $folders[] = $file;
1068 }
1069 }
1070}
1071
1072if (!empty($files)) {
1073 natcasesort($files);
1074}
1075if (!empty($folders)) {
1076 natcasesort($folders);
1077}
1078
1079// upload form
1080if (isset($_GET['upload']) && !FM_READONLY) {
1081 fm_show_header(); // HEADER
1082 fm_show_nav_path(FM_PATH); // current path
1083 //get the allowed file extensions
1084 function getUploadExt() {
1085 $extArr = explode(',', FM_UPLOAD_EXTENSION);
1086 if(FM_UPLOAD_EXTENSION && $extArr) {
1087 array_walk($extArr, function(&$x) {$x = ".$x";});
1088 return implode(',', $extArr);
1089 }
1090 return '';
1091 }
1092 ?>
1093
1094 <link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.css" rel="stylesheet">
1095 <div class="path">
1096
1097 <div class="card mb-2 fm-upload-wrapper">
1098 <div class="card-header">
1099 <ul class="nav nav-tabs card-header-tabs">
1100 <li class="nav-item">
1101 <a class="nav-link active" href="#fileUploader" data-target="#fileUploader"><i class="fa fa-arrow-circle-o-up"></i> <?php echo lng('UploadingFiles') ?></a>
1102 </li>
1103 <li class="nav-item">
1104 <a class="nav-link" href="#urlUploader" class="js-url-upload" data-target="#urlUploader"><i class="fa fa-link"></i> Upload from URL</a>
1105 </li>
1106 </ul>
1107 </div>
1108 <div class="card-body">
1109 <p class="card-text">
1110 <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>
1111 <?php echo lng('DestinationFolder') ?>: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?>
1112 </p>
1113
1114 <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]) . '?p=' . fm_enc(FM_PATH) ?>" class="dropzone card-tabs-container" id="fileUploader" enctype="multipart/form-data">
1115 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1116 <input type="hidden" name="fullpath" id="fullpath" value="<?php echo fm_enc(FM_PATH) ?>">
1117 <div class="fallback">
1118 <input name="file" type="file" multiple/>
1119 </div>
1120 </form>
1121
1122 <div class="upload-url-wrapper card-tabs-container hidden" id="urlUploader">
1123 <form id="js-form-url-upload" class="form-inline" onsubmit="return upload_from_url(this);" method="POST" action="">
1124 <input type="hidden" name="type" value="upload" aria-label="hidden" aria-hidden="true">
1125 <input type="url" placeholder="URL" name="uploadurl" required class="form-control" style="width: 80%">
1126 <button type="submit" class="btn btn-primary ml-3"><?php echo lng('Upload') ?></button>
1127 <div class="lds-facebook"><div></div><div></div><div></div></div>
1128 </form>
1129 <div id="js-url-upload__list" class="col-9 mt-3"></div>
1130 </div>
1131 </div>
1132 </div>
1133 </div>
1134 <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/min/dropzone.min.js"></script>
1135 <script>
1136 Dropzone.options.fileUploader = {
1137 timeout: 120000,
1138 maxFilesize: <?php echo MAX_UPLOAD_SIZE; ?>,
1139 acceptedFiles : "<?php echo getUploadExt() ?>",
1140 init: function () {
1141 this.on("sending", function (file, xhr, formData) {
1142 let _path = (file.fullPath) ? file.fullPath : file.name;
1143 document.getElementById("fullpath").value = _path;
1144 xhr.ontimeout = (function() {
1145 toast('Error: Server Timeout');
1146 });
1147 }).on("success", function (res) {
1148 let _response = JSON.parse(res.xhr.response);
1149 if(_response.status == "error") {
1150 toast(_response.info);
1151 }
1152 }).on("error", function(file, response) {
1153 toast(response);
1154 });
1155 }
1156 }
1157 </script>
1158 <?php
1159 fm_show_footer();
1160 exit;
1161}
1162
1163// copy form POST
1164if (isset($_POST['copy']) && !FM_READONLY) {
1165 $copy_files = isset($_POST['file']) ? $_POST['file'] : null;
1166 if (!is_array($copy_files) || empty($copy_files)) {
1167 fm_set_msg('Nothing selected', 'alert');
1168 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1169 }
1170
1171 fm_show_header(); // HEADER
1172 fm_show_nav_path(FM_PATH); // current path
1173 ?>
1174 <div class="path">
1175 <div class="card">
1176 <div class="card-header">
1177 <h6><?php echo lng('Copying') ?></h6>
1178 </div>
1179 <div class="card-body">
1180 <form action="" method="post">
1181 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1182 <input type="hidden" name="finish" value="1">
1183 <?php
1184 foreach ($copy_files as $cf) {
1185 echo '<input type="hidden" name="file[]" value="' . fm_enc($cf) . '">' . PHP_EOL;
1186 }
1187 ?>
1188 <p class="break-word"><?php echo lng('Files') ?>: <b><?php echo implode('</b>, <b>', $copy_files) ?></b></p>
1189 <p class="break-word"><?php echo lng('SourceFolder') ?>: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?><br>
1190 <label for="inp_copy_to"><?php echo lng('DestinationFolder') ?>:</label>
1191 <?php echo FM_ROOT_PATH ?>/<input type="text" name="copy_to" id="inp_copy_to" value="<?php echo fm_enc(FM_PATH) ?>">
1192 </p>
1193 <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>
1194 <p>
1195 <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo lng('Copy') ?></button>
1196 <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>
1197 </p>
1198 </form>
1199 </div>
1200 </div>
1201 </div>
1202 <?php
1203 fm_show_footer();
1204 exit;
1205}
1206
1207// copy form
1208if (isset($_GET['copy']) && !isset($_GET['finish']) && !FM_READONLY) {
1209 $copy = $_GET['copy'];
1210 $copy = fm_clean_path($copy);
1211 if ($copy == '' || !file_exists(FM_ROOT_PATH . '/' . $copy)) {
1212 fm_set_msg('File not found', 'error');
1213 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1214 }
1215
1216 fm_show_header(); // HEADER
1217 fm_show_nav_path(FM_PATH); // current path
1218 ?>
1219 <div class="path">
1220 <p><b>Copying</b></p>
1221 <p class="break-word">
1222 Source path: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . $copy)) ?><br>
1223 Destination folder: <?php echo fm_enc(fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?>
1224 </p>
1225 <p>
1226 <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>
1227 <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>
1228 <b><a href="?p=<?php echo urlencode(FM_PATH) ?>"><i class="fa fa-times-circle"></i> Cancel</a></b>
1229 </p>
1230 <p><i>Select folder</i></p>
1231 <ul class="folders break-word">
1232 <?php
1233 if ($parent !== false) {
1234 ?>
1235 <li><a href="?p=<?php echo urlencode($parent) ?>&copy=<?php echo urlencode($copy) ?>"><i class="fa fa-chevron-circle-left"></i> ..</a></li>
1236 <?php
1237 }
1238 foreach ($folders as $f) {
1239 ?>
1240 <li>
1241 <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>
1242 <?php
1243 }
1244 ?>
1245 </ul>
1246 </div>
1247 <?php
1248 fm_show_footer();
1249 exit;
1250}
1251
1252if (isset($_GET['settings']) && !FM_READONLY) {
1253 fm_show_header(); // HEADER
1254 fm_show_nav_path(FM_PATH); // current path
1255 global $cfg, $lang, $lang_list;
1256 ?>
1257
1258 <div class="col-md-8 offset-md-2 pt-3">
1259 <div class="card mb-2">
1260 <h6 class="card-header">
1261 <i class="fa fa-cog"></i> <?php echo lng('Settings') ?>
1262 <a href="?p=<?php echo FM_PATH ?>" class="float-right"><i class="fa fa-window-close"></i> <?php echo lng('Cancel')?></a>
1263 </h6>
1264 <div class="card-body">
1265 <form id="js-settings-form" action="" method="post" data-type="ajax" onsubmit="return save_settings(this)">
1266 <input type="hidden" name="type" value="settings" aria-label="hidden" aria-hidden="true">
1267 <div class="form-group row">
1268 <label for="js-language" class="col-sm-3 col-form-label"><?php echo lng('Language') ?></label>
1269 <div class="col-sm-5">
1270 <select class="form-control" id="js-language" name="js-language">
1271 <?php
1272 function getSelected($l) {
1273 global $lang;
1274 return ($lang == $l) ? 'selected' : '';
1275 }
1276 foreach ($lang_list as $k => $v) {
1277 echo "<option value='$k' ".getSelected($k).">$v</option>";
1278 }
1279 ?>
1280 </select>
1281 </div>
1282 </div>
1283 <?php
1284 //get ON/OFF and active class
1285 function getChecked($conf, $val, $txt) {
1286 if($conf== 1 && $val ==1) {
1287 return $txt;
1288 } else if($conf == '' && $val == '') {
1289 return $txt;
1290 } else {
1291 return '';
1292 }
1293 }
1294 ?>
1295 <div class="form-group row">
1296 <label for="js-err-rpt-1" class="col-sm-3 col-form-label"><?php echo lng('ErrorReporting') ?></label>
1297 <div class="col-sm-9">
1298 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1299 <label class="btn btn-secondary <?php echo getChecked($report_errors, 1, 'active') ?>">
1300 <input type="radio" name="js-error-report" id="js-err-rpt-1" autocomplete="off" value="true" <?php echo getChecked($report_errors, 1, 'checked') ?> > ON
1301 </label>
1302 <label class="btn btn-secondary <?php echo getChecked($report_errors, '', 'active') ?>">
1303 <input type="radio" name="js-error-report" id="js-err-rpt-0" autocomplete="off" value="false" <?php echo getChecked($report_errors, '', 'checked') ?> > OFF
1304 </label>
1305 </div>
1306 </div>
1307 </div>
1308
1309 <div class="form-group row">
1310 <label for="js-hdn-1" class="col-sm-3 col-form-label"><?php echo lng('ShowHiddenFiles') ?></label>
1311 <div class="col-sm-9">
1312 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1313 <label class="btn btn-secondary <?php echo getChecked($show_hidden_files, 1, 'active') ?>">
1314 <input type="radio" name="js-show-hidden" id="js-hdn-1" autocomplete="off" value="true" <?php echo getChecked($show_hidden_files, 1, 'checked') ?> > ON
1315 </label>
1316 <label class="btn btn-secondary <?php echo getChecked($show_hidden_files, '', 'active') ?>">
1317 <input type="radio" name="js-show-hidden" id="js-hdn-0" autocomplete="off" value="false" <?php echo getChecked($show_hidden_files, '', 'checked') ?> > OFF
1318 </label>
1319 </div>
1320 </div>
1321 </div>
1322
1323 <div class="form-group row">
1324 <label for="js-hid-1" class="col-sm-3 col-form-label"><?php echo lng('HideColumns') ?></label>
1325 <div class="col-sm-9">
1326 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1327 <label class="btn btn-secondary <?php echo getChecked($hide_Cols, 1, 'active') ?>">
1328 <input type="radio" name="js-hide-cols" id="js-hid-1" autocomplete="off" value="true" <?php echo getChecked($hide_Cols, 1, 'checked') ?> > ON
1329 </label>
1330 <label class="btn btn-secondary <?php echo getChecked($hide_Cols, '', 'active') ?>">
1331 <input type="radio" name="js-hide-cols" id="js-hid-0" autocomplete="off" value="false" <?php echo getChecked($hide_Cols, '', 'checked') ?> > OFF
1332 </label>
1333 </div>
1334 </div>
1335 </div>
1336
1337 <div class="form-group row">
1338 <label for="js-dir-1" class="col-sm-3 col-form-label"><?php echo lng('CalculateFolderSize') ?></label>
1339 <div class="col-sm-9">
1340 <div class="btn-group btn-group-toggle" data-toggle="buttons">
1341 <label class="btn btn-secondary <?php echo getChecked($calc_folder, 1, 'active') ?>">
1342 <input type="radio" name="js-calc-folder" id="js-dir-1" autocomplete="off" value="true" <?php echo getChecked($calc_folder, 1, 'checked') ?> > ON
1343 </label>
1344 <label class="btn btn-secondary <?php echo getChecked($calc_folder, '', 'active') ?>">
1345 <input type="radio" name="js-calc-folder" id="js-dir-0" autocomplete="off" value="false" <?php echo getChecked($calc_folder, '', 'checked') ?> > OFF
1346 </label>
1347 </div>
1348 </div>
1349 </div>
1350
1351 <div class="form-group row">
1352 <div class="col-sm-10">
1353 <button type="submit" class="btn btn-success"> <i class="fa fa-check-circle"></i> <?php echo lng('Save'); ?></button>
1354 </div>
1355 </div>
1356
1357 </form>
1358 </div>
1359 </div>
1360 </div>
1361 <?php
1362 fm_show_footer();
1363 exit;
1364}
1365
1366if (isset($_GET['help'])) {
1367 fm_show_header(); // HEADER
1368 fm_show_nav_path(FM_PATH); // current path
1369 global $cfg, $lang;
1370 ?>
1371
1372 <div class="col-md-8 offset-md-2 pt-3">
1373 <div class="card mb-2">
1374 <h6 class="card-header">
1375 <i class="fa fa-exclamation-circle"></i> <?php echo lng('Help') ?>
1376 <a href="?p=<?php echo FM_PATH ?>" class="float-right"><i class="fa fa-window-close"></i> <?php echo lng('Cancel')?></a>
1377 </h6>
1378 <div class="card-body">
1379 <div class="row">
1380 <div class="col-xs-12 col-sm-6">
1381 <p><h3><a href="https://github.com/prasathmani/tinyfilemanager" target="_blank" class="app-v-title"> Tiny File Manager <?php echo VERSION; ?></a></h3></p>
1382 <p>Author: Prasath Mani</p>
1383 <p>Mail Us: <a href="mailto:ccpprogrammers@gmail.com">ccpprogrammers[at]gmail.com</a> </p>
1384 </div>
1385 <div class="col-xs-12 col-sm-6">
1386 <div class="card">
1387 <ul class="list-group list-group-flush">
1388 <li class="list-group-item"><a href="https://github.com/prasathmani/tinyfilemanager/wiki" target="_blank"><i class="fa fa-question-circle"></i> <?php echo lng('Help Documents') ?> </a> </li>
1389 <li class="list-group-item"><a href="https://github.com/prasathmani/tinyfilemanager/issues" target="_blank"><i class="fa fa-bug"></i> <?php echo lng('Report Issue') ?></a></li>
1390 <li class="list-group-item"><a href="javascript:latest_release_info('<?php echo VERSION; ?>');"><i class="fa fa-link"> </i> <?php echo lng('Check Latest Version') ?></a></li>
1391 <?php if(!FM_READONLY) { ?>
1392 <li class="list-group-item"><a href="javascript:show_new_pwd();"><i class="fa fa-lock"></i> <?php echo lng('Generate new password hash') ?></a></li>
1393 <?php } ?>
1394 </ul>
1395 </div>
1396 </div>
1397 </div>
1398 <div class="row js-new-pwd hidden mt-2">
1399 <div class="col-12">
1400 <form class="form-inline" onsubmit="return new_password_hash(this)" method="POST" action="">
1401 <input type="hidden" name="type" value="pwdhash" aria-label="hidden" aria-hidden="true">
1402 <div class="form-group mb-2">
1403 <label for="staticEmail2"><?php echo lng('Generate new password hash') ?></label>
1404 </div>
1405 <div class="form-group mx-sm-3 mb-2">
1406 <label for="inputPassword2" class="sr-only"><?php echo lng('Password') ?></label>
1407 <input type="text" class="form-control btn-sm" id="inputPassword2" name="inputPassword2" placeholder="Password" required>
1408 </div>
1409 <button type="submit" class="btn btn-success btn-sm mb-2"><?php echo lng('Generate') ?></button>
1410 </form>
1411 <textarea class="form-control" rows="2" readonly id="js-pwd-result"></textarea>
1412 </div>
1413 </div>
1414 </div>
1415 </div>
1416 </div>
1417 <?php
1418 fm_show_footer();
1419 exit;
1420}
1421
1422// file viewer
1423if (isset($_GET['view'])) {
1424 $file = $_GET['view'];
1425 $quickView = (isset($_GET['quickView']) && $_GET['quickView'] == 1) ? true : false;
1426 $file = fm_clean_path($file, false);
1427 $file = str_replace('/', '', $file);
1428 if ($file == '' || !is_file($path . '/' . $file) || in_array($file, $GLOBALS['exclude_items'])) {
1429 fm_set_msg('File not found', 'error');
1430 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1431 }
1432
1433 if(!$quickView) {
1434 fm_show_header(); // HEADER
1435 fm_show_nav_path(FM_PATH); // current path
1436 }
1437
1438 $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
1439 $file_path = $path . '/' . $file;
1440
1441 $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
1442 $mime_type = fm_get_mime_type($file_path);
1443 $filesize = fm_get_filesize(filesize($file_path));
1444
1445 $is_zip = false;
1446 $is_gzip = false;
1447 $is_image = false;
1448 $is_audio = false;
1449 $is_video = false;
1450 $is_text = false;
1451 $is_onlineViewer = false;
1452
1453 $view_title = 'File';
1454 $filenames = false; // for zip
1455 $content = ''; // for text
1456 $online_viewer = strtolower(FM_DOC_VIEWER);
1457
1458 if($online_viewer && $online_viewer !== 'false' && in_array($ext, fm_get_onlineViewer_exts())){
1459 $is_onlineViewer = true;
1460 }
1461 elseif ($ext == 'zip' || $ext == 'tar') {
1462 $is_zip = true;
1463 $view_title = 'Archive';
1464 $filenames = fm_get_zif_info($file_path, $ext);
1465 } elseif (in_array($ext, fm_get_image_exts())) {
1466 $is_image = true;
1467 $view_title = 'Image';
1468 } elseif (in_array($ext, fm_get_audio_exts())) {
1469 $is_audio = true;
1470 $view_title = 'Audio';
1471 } elseif (in_array($ext, fm_get_video_exts())) {
1472 $is_video = true;
1473 $view_title = 'Video';
1474 } elseif (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) {
1475 $is_text = true;
1476 $content = file_get_contents($file_path);
1477 }
1478
1479 ?>
1480 <div class="row">
1481 <div class="col-12">
1482 <?php if(!$quickView) { ?>
1483 <p class="break-word"><b><?php echo $view_title ?> "<?php echo fm_enc(fm_convert_win($file)) ?>"</b></p>
1484 <p class="break-word">
1485 Full path: <?php echo fm_enc(fm_convert_win($file_path)) ?><br>
1486 File
1487 size: <?php echo fm_get_filesize($filesize) ?><?php if ($filesize >= 1000): ?> (<?php echo sprintf('%s bytes', $filesize) ?>)<?php endif; ?>
1488 <br>
1489 MIME-type: <?php echo $mime_type ?><br>
1490 <?php
1491 // ZIP info
1492 if (($is_zip || $is_gzip) && $filenames !== false) {
1493 $total_files = 0;
1494 $total_comp = 0;
1495 $total_uncomp = 0;
1496 foreach ($filenames as $fn) {
1497 if (!$fn['folder']) {
1498 $total_files++;
1499 }
1500 $total_comp += $fn['compressed_size'];
1501 $total_uncomp += $fn['filesize'];
1502 }
1503 ?>
1504 Files in archive: <?php echo $total_files ?><br>
1505 Total size: <?php echo fm_get_filesize($total_uncomp) ?><br>
1506 Size in archive: <?php echo fm_get_filesize($total_comp) ?><br>
1507 Compression: <?php echo round(($total_comp / $total_uncomp) * 100) ?>%<br>
1508 <?php
1509 }
1510 // Image info
1511 if ($is_image) {
1512 $image_size = getimagesize($file_path);
1513 echo 'Image sizes: ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '<br>';
1514 }
1515 // Text info
1516 if ($is_text) {
1517 $is_utf8 = fm_is_utf8($content);
1518 if (function_exists('iconv')) {
1519 if (!$is_utf8) {
1520 $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content);
1521 }
1522 }
1523 echo 'Charset: ' . ($is_utf8 ? 'utf-8' : '8 bit') . '<br>';
1524 }
1525 ?>
1526 </p>
1527 <p>
1528 <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>
1529 <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>
1530
1531 <?php
1532 // ZIP actions
1533 if (!FM_READONLY && ($is_zip || $is_gzip) && $filenames !== false) {
1534 $zip_name = pathinfo($file_path, PATHINFO_FILENAME);
1535 ?>
1536 <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>
1537 <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>
1538 <?php echo lng('UnZipToFolder') ?></a></b>
1539 <?php
1540 }
1541 if ($is_text && !FM_READONLY) {
1542 ?>
1543 <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') ?>
1544 </a></b>
1545 <b><a href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&edit=<?php echo urlencode($file) ?>&env=ace"
1546 class="edit-file"><i class="fa fa-pencil-square-o"></i> <?php echo lng('AdvancedEditor') ?>
1547 </a></b>
1548 <?php } ?>
1549 <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>
1550 </p>
1551 <?php
1552 }
1553 if($is_onlineViewer) {
1554 if($online_viewer == 'google') {
1555 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>';
1556 } else if($online_viewer == 'microsoft') {
1557 echo '<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=' . fm_enc($file_url) . '" frameborder="no" style="width:100%;min-height:460px"></iframe>';
1558 }
1559 } elseif ($is_zip) {
1560 // ZIP content
1561 if ($filenames !== false) {
1562 echo '<code class="maxheight">';
1563 foreach ($filenames as $fn) {
1564 if ($fn['folder']) {
1565 echo '<b>' . fm_enc($fn['name']) . '</b><br>';
1566 } else {
1567 echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')<br>';
1568 }
1569 }
1570 echo '</code>';
1571 } else {
1572 echo '<p>Error while fetching archive info</p>';
1573 }
1574 } elseif ($is_image) {
1575 // Image content
1576 if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg'))) {
1577 echo '<p><img src="' . fm_enc($file_url) . '" alt="" class="preview-img"></p>';
1578 }
1579 } elseif ($is_audio) {
1580 // Audio content
1581 echo '<p><audio src="' . fm_enc($file_url) . '" controls preload="metadata"></audio></p>';
1582 } elseif ($is_video) {
1583 // Video content
1584 echo '<div class="preview-video"><video src="' . fm_enc($file_url) . '" width="640" height="360" controls preload="metadata"></video></div>';
1585 } elseif ($is_text) {
1586 if (FM_USE_HIGHLIGHTJS) {
1587 // highlight
1588 $hljs_classes = array(
1589 'shtml' => 'xml',
1590 'htaccess' => 'apache',
1591 'phtml' => 'php',
1592 'lock' => 'json',
1593 'svg' => 'xml',
1594 );
1595 $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext;
1596 if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) {
1597 $hljs_class = 'nohighlight';
1598 }
1599 $content = '<pre class="with-hljs"><code class="' . $hljs_class . '">' . fm_enc($content) . '</code></pre>';
1600 } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) {
1601 // php highlight
1602 $content = highlight_string($content, true);
1603 } else {
1604 $content = '<pre>' . fm_enc($content) . '</pre>';
1605 }
1606 echo $content;
1607 }
1608 ?>
1609 </div>
1610 </div>
1611 <?php
1612 if(!$quickView) {
1613 fm_show_footer();
1614 }
1615 exit;
1616}
1617
1618// file editor
1619if (isset($_GET['edit'])) {
1620 $file = $_GET['edit'];
1621 $file = fm_clean_path($file, false);
1622 $file = str_replace('/', '', $file);
1623 if ($file == '' || !is_file($path . '/' . $file)) {
1624 fm_set_msg('File not found', 'error');
1625 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1626 }
1627 header('X-XSS-Protection:0');
1628 fm_show_header(); // HEADER
1629 fm_show_nav_path(FM_PATH); // current path
1630
1631 $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
1632 $file_path = $path . '/' . $file;
1633
1634 // normal editer
1635 $isNormalEditor = true;
1636 if (isset($_GET['env'])) {
1637 if ($_GET['env'] == "ace") {
1638 $isNormalEditor = false;
1639 }
1640 }
1641
1642 // Save File
1643 if (isset($_POST['savedata'])) {
1644 $writedata = $_POST['savedata'];
1645 $fd = fopen($file_path, "w");
1646 @fwrite($fd, $writedata);
1647 fclose($fd);
1648 fm_set_msg('File Saved Successfully');
1649 }
1650
1651 $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
1652 $mime_type = fm_get_mime_type($file_path);
1653 $filesize = filesize($file_path);
1654 $is_text = false;
1655 $content = ''; // for text
1656
1657 if (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) {
1658 $is_text = true;
1659 $content = file_get_contents($file_path);
1660 }
1661
1662 ?>
1663 <div class="path">
1664 <div class="row">
1665 <div class="col-xs-12 col-sm-5 col-lg-6 pt-1">
1666 <div class="btn-toolbar" role="toolbar">
1667 <?php if (!$isNormalEditor) { ?>
1668 <div class="btn-group js-ace-toolbar">
1669 <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>
1670 <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>
1671 <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>
1672 <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>
1673 <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>
1674 <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>
1675 <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>
1676 <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>
1677 <select id="js-ace-fontSize" data-type="fontSize" title="Selct Font Size" class="btn-outline-secondary border-left-0 d-none d-lg-block"><option>-- Select Font Size --</option></select>
1678 </div>
1679 <?php } ?>
1680 </div>
1681 </div>
1682 <div class="edit-file-actions col-xs-12 col-sm-7 col-lg-6 text-right pt-1">
1683 <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>
1684 <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>
1685 <?php if ($is_text) { ?>
1686 <?php if ($isNormalEditor) { ?>
1687 <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>
1688 <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
1689 </button>
1690 <?php } else { ?>
1691 <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>
1692 <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') ?>
1693 </button>
1694 <?php } ?>
1695 <?php } ?>
1696 </div>
1697 </div>
1698 <?php
1699 if ($is_text && $isNormalEditor) {
1700 echo '<textarea class="mt-2" id="normal-editor" rows="33" cols="120" style="width: 99.5%;">' . htmlspecialchars($content) . '</textarea>';
1701 } elseif ($is_text) {
1702 echo '<div id="editor" contenteditable="true">' . htmlspecialchars($content) . '</div>';
1703 } else {
1704 fm_set_msg('FILE EXTENSION HAS NOT SUPPORTED', 'error');
1705 }
1706 ?>
1707 </div>
1708 <?php
1709 fm_show_footer();
1710 exit;
1711}
1712
1713// chmod (not for Windows)
1714if (isset($_GET['chmod']) && !FM_READONLY && !FM_IS_WIN) {
1715 $file = $_GET['chmod'];
1716 $file = fm_clean_path($file);
1717 $file = str_replace('/', '', $file);
1718 if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
1719 fm_set_msg('File not found', 'error');
1720 fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
1721 }
1722
1723 fm_show_header(); // HEADER
1724 fm_show_nav_path(FM_PATH); // current path
1725
1726 $file_url = FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file;
1727 $file_path = $path . '/' . $file;
1728
1729 $mode = fileperms($path . '/' . $file);
1730
1731 ?>
1732 <div class="path">
1733 <div class="card mb-2">
1734 <h6 class="card-header">
1735 <?php echo lng('ChangePermissions') ?>
1736 </h6>
1737 <div class="card-body">
1738 <p class="card-text">
1739 Full path: <?php echo $file_path ?><br>
1740 </p>
1741 <form action="" method="post">
1742 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1743 <input type="hidden" name="chmod" value="<?php echo fm_enc($file) ?>">
1744
1745 <table class="table compact-table">
1746 <tr>
1747 <td></td>
1748 <td><b><?php echo lng('Owner') ?></b></td>
1749 <td><b><?php echo lng('Group') ?></b></td>
1750 <td><b><?php echo lng('Other') ?></b></td>
1751 </tr>
1752 <tr>
1753 <td style="text-align: right"><b><?php echo lng('Read') ?></b></td>
1754 <td><label><input type="checkbox" name="ur" value="1"<?php echo ($mode & 00400) ? ' checked' : '' ?>></label></td>
1755 <td><label><input type="checkbox" name="gr" value="1"<?php echo ($mode & 00040) ? ' checked' : '' ?>></label></td>
1756 <td><label><input type="checkbox" name="or" value="1"<?php echo ($mode & 00004) ? ' checked' : '' ?>></label></td>
1757 </tr>
1758 <tr>
1759 <td style="text-align: right"><b><?php echo lng('Write') ?></b></td>
1760 <td><label><input type="checkbox" name="uw" value="1"<?php echo ($mode & 00200) ? ' checked' : '' ?>></label></td>
1761 <td><label><input type="checkbox" name="gw" value="1"<?php echo ($mode & 00020) ? ' checked' : '' ?>></label></td>
1762 <td><label><input type="checkbox" name="ow" value="1"<?php echo ($mode & 00002) ? ' checked' : '' ?>></label></td>
1763 </tr>
1764 <tr>
1765 <td style="text-align: right"><b><?php echo lng('Execute') ?></b></td>
1766 <td><label><input type="checkbox" name="ux" value="1"<?php echo ($mode & 00100) ? ' checked' : '' ?>></label></td>
1767 <td><label><input type="checkbox" name="gx" value="1"<?php echo ($mode & 00010) ? ' checked' : '' ?>></label></td>
1768 <td><label><input type="checkbox" name="ox" value="1"<?php echo ($mode & 00001) ? ' checked' : '' ?>></label></td>
1769 </tr>
1770 </table>
1771
1772 <p>
1773 <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo lng('Change') ?></button>
1774 <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>
1775 </p>
1776 </form>
1777 </div>
1778 </div>
1779 </div>
1780 <?php
1781 fm_show_footer();
1782 exit;
1783}
1784
1785//--- FILEMANAGER MAIN
1786fm_show_header(); // HEADER
1787fm_show_nav_path(FM_PATH); // current path
1788
1789// messages
1790fm_show_message();
1791
1792$num_files = count($files);
1793$num_folders = count($folders);
1794$all_files_size = 0;
1795?>
1796<form action="" method="post" class="pt-3">
1797 <input type="hidden" name="p" value="<?php echo fm_enc(FM_PATH) ?>">
1798 <input type="hidden" name="group" value="1">
1799 <div class="table-responsive">
1800 <table class="table table-bordered table-hover table-sm bg-white" id="main-table">
1801 <thead class="thead-white">
1802 <tr>
1803 <?php if (!FM_READONLY): ?>
1804 <th style="width:3%" class="custom-checkbox-header">
1805 <div class="custom-control custom-checkbox">
1806 <input type="checkbox" class="custom-control-input" id="js-select-all-items" onclick="checkbox_toggle()">
1807 <label class="custom-control-label" for="js-select-all-items"></label>
1808 </div>
1809 </th><?php endif; ?>
1810 <th><?php echo lng('Name') ?></th>
1811 <th><?php echo lng('Size') ?></th>
1812 <th><?php echo lng('Modified') ?></th>
1813 <?php if (!FM_IS_WIN && !$hide_Cols): ?>
1814 <th><?php echo lng('Perms') ?></th>
1815 <th><?php echo lng('Owner') ?></th><?php endif; ?>
1816 <th><?php echo lng('Actions') ?></th>
1817 </tr>
1818 </thead>
1819 <?php
1820 // link to parent folder
1821 if ($parent !== false) {
1822 ?>
1823 <tr><?php if (!FM_READONLY): ?>
1824 <td class="nosort"></td><?php endif; ?>
1825 <td class="border-0"><a href="?p=<?php echo urlencode($parent) ?>"><i class="fa fa-chevron-circle-left go-back"></i> ..</a></td>
1826 <td class="border-0"></td>
1827 <td class="border-0"></td>
1828 <td class="border-0"></td>
1829 <?php if (!FM_IS_WIN && !$hide_Cols) { ?>
1830 <td class="border-0"></td>
1831 <td class="border-0"></td>
1832 <?php } ?>
1833 </tr>
1834 <?php
1835 }
1836 $ii = 3399;
1837 foreach ($folders as $f) {
1838 $is_link = is_link($path . '/' . $f);
1839 $img = $is_link ? 'icon-link_folder' : 'fa fa-folder-o';
1840 $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
1841 $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
1842 if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
1843 $owner = posix_getpwuid(fileowner($path . '/' . $f));
1844 $group = posix_getgrgid(filegroup($path . '/' . $f));
1845 } else {
1846 $owner = array('name' => '?');
1847 $group = array('name' => '?');
1848 }
1849 ?>
1850 <tr>
1851 <?php if (!FM_READONLY): ?>
1852 <td class="custom-checkbox-td">
1853 <div class="custom-control custom-checkbox">
1854 <input type="checkbox" class="custom-control-input" id="<?php echo $ii ?>" name="file[]" value="<?php echo fm_enc($f) ?>">
1855 <label class="custom-control-label" for="<?php echo $ii ?>"></label>
1856 </div>
1857 </td><?php endif; ?>
1858 <td>
1859 <div class="filename"><a href="?p=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="<?php echo $img ?>"></i> <?php echo fm_convert_win(fm_enc($f)) ?>
1860 </a><?php echo($is_link ? ' → <i>' . readlink($path . '/' . $f) . '</i>' : '') ?></div>
1861 </td>
1862 <td><?php if ($calc_folder) { echo fm_get_directorysize($path . '/' . $f); } else { echo lng('Folder'); } ?></td>
1863 <td><?php echo $modif ?></td>
1864 <?php if (!FM_IS_WIN && !$hide_Cols): ?>
1865 <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; ?>
1866 </td>
1867 <td><?php echo $owner['name'] . ':' . $group['name'] ?></td>
1868 <?php endif; ?>
1869 <td class="inline-actions"><?php if (!FM_READONLY): ?>
1870 <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>
1871 <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>
1872 <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>
1873 <?php endif; ?>
1874 <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>
1875 </td>
1876 </tr>
1877 <?php
1878 flush();
1879 $ii++;
1880 }
1881 $ik = 6070;
1882 foreach ($files as $f) {
1883 $is_link = is_link($path . '/' . $f);
1884 $img = $is_link ? 'fa fa-file-text-o' : fm_get_file_icon_class($path . '/' . $f);
1885 $modif = date(FM_DATETIME_FORMAT, filemtime($path . '/' . $f));
1886 $filesize_raw = fm_get_size($path . '/' . $f);
1887 $filesize = fm_get_filesize($filesize_raw);
1888 $filelink = '?p=' . urlencode(FM_PATH) . '&view=' . urlencode($f);
1889 $all_files_size += $filesize_raw;
1890 $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
1891 if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
1892 $owner = posix_getpwuid(fileowner($path . '/' . $f));
1893 $group = posix_getgrgid(filegroup($path . '/' . $f));
1894 } else {
1895 $owner = array('name' => '?');
1896 $group = array('name' => '?');
1897 }
1898 ?>
1899 <tr>
1900 <?php if (!FM_READONLY): ?>
1901 <td class="custom-checkbox-td">
1902 <div class="custom-control custom-checkbox">
1903 <input type="checkbox" class="custom-control-input" id="<?php echo $ik ?>" name="file[]" value="<?php echo fm_enc($f) ?>">
1904 <label class="custom-control-label" for="<?php echo $ik ?>"></label>
1905 </div>
1906 </td><?php endif; ?>
1907 <td>
1908 <div class="filename">
1909 <?php
1910 if (in_array(strtolower(pathinfo($f, PATHINFO_EXTENSION)), array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg'))): ?>
1911 <?php $imagePreview = fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $f); ?>
1912 <a href="<?php echo $filelink ?>" data-preview-image="<?php echo $imagePreview ?>" title="<?php echo $f ?>">
1913 <?php else: ?>
1914 <a href="<?php echo $filelink ?>" title="<?php echo $f ?>">
1915 <?php endif; ?>
1916 <i class="<?php echo $img ?>"></i> <?php echo fm_convert_win($f) ?>
1917 </a>
1918 <?php echo($is_link ? ' → <i>' . readlink($path . '/' . $f) . '</i>' : '') ?>
1919 </div>
1920 </td>
1921 <td><span title="<?php printf('%s bytes', $filesize_raw) ?>">
1922 <?php echo $filesize; ?>
1923 </span></td>
1924 <td><?php echo $modif ?></td>
1925 <?php if (!FM_IS_WIN && !$hide_Cols): ?>
1926 <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; ?>
1927 </td>
1928 <td><?php echo fm_enc($owner['name'] . ':' . $group['name']) ?></td>
1929 <?php endif; ?>
1930 <td class="inline-actions">
1931 <a title="<?php echo lng('Preview') ?>" href="<?php echo $filelink.'&quickView=1'; ?>" data-toggle="lightbox" data-gallery="tiny-gallery" data-title="<?php echo fm_convert_win($f) ?>" data-max-width="100%" data-width="100%"><i class="fa fa-eye"></i></a>
1932 <?php if (!FM_READONLY): ?>
1933 <a title="<?php echo lng('Delete') ?>" href="?p=<?php echo urlencode(FM_PATH) ?>&del=<?php echo urlencode($f) ?>" onclick="return confirm('<?php echo lng('Delete').' '.lng('File').'?'; ?>');"><i class="fa fa-trash-o"></i></a>
1934 <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>
1935 <a title="<?php echo lng('CopyTo') ?>..."
1936 href="?p=<?php echo urlencode(FM_PATH) ?>&copy=<?php echo urlencode(trim(FM_PATH . '/' . $f, '/')) ?>"><i class="fa fa-files-o"></i></a>
1937 <?php endif; ?>
1938 <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>
1939 <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>
1940 </td>
1941 </tr>
1942 <?php
1943 flush();
1944 $ik++;
1945 }
1946
1947 if (empty($folders) && empty($files)) {
1948 ?>
1949 <tfoot>
1950 <tr><?php if (!FM_READONLY): ?>
1951 <td></td><?php endif; ?>
1952 <td colspan="<?php echo (!FM_IS_WIN && !$hide_Cols) ? '6' : '4' ?>"><em><?php echo 'Folder is empty' ?></em></td>
1953 </tr>
1954 </tfoot>
1955 <?php
1956 } else {
1957 ?>
1958 <tfoot>
1959 <tr><?php if (!FM_READONLY): ?>
1960 <td class="gray"></td><?php endif; ?>
1961 <td class="gray" colspan="<?php echo (!FM_IS_WIN && !$hide_Cols) ? '6' : '4' ?>">
1962 <?php echo lng('FullSize').': <span class="badge badge-light">'.fm_get_filesize($all_files_size).'</span>' ?>
1963 <?php echo lng('File').': <span class="badge badge-light">'.$num_files.'</span>' ?>
1964 <?php echo lng('Folder').': <span class="badge badge-light">'.$num_folders.'</span>' ?>
1965 <?php echo lng('MemoryUsed').': <span class="badge badge-light">'.fm_get_filesize(@memory_get_usage(true)).'</span>' ?>
1966 <?php echo lng('PartitionSize').': <span class="badge badge-light">'.fm_get_filesize(@disk_free_space($path)) .'</span> '.lng('FreeOf').' <span class="badge badge-light">'.fm_get_filesize(@disk_total_space($path)).'</span>'; ?>
1967 </td>
1968 </tr>
1969 </tfoot>
1970 <?php
1971 }
1972 ?>
1973 </table>
1974 </div>
1975
1976 <div class="row">
1977 <?php if (!FM_READONLY): ?>
1978 <div class="col-xs-12 col-sm-9">
1979 <ul class="list-inline footer-action">
1980 <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>
1981 <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>
1982 <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>
1983 <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?')">
1984 <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>
1985 <li class="list-inline-item"><input type="submit" class="hidden" name="zip" id="a-zip" value="zip" onclick="return confirm('Create archive?')">
1986 <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>
1987 <li class="list-inline-item"><input type="submit" class="hidden" name="tar" id="a-tar" value="tar" onclick="return confirm('Create archive?')">
1988 <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>
1989 <li class="list-inline-item"><input type="submit" class="hidden" name="copy" id="a-copy" value="Copy">
1990 <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>
1991 </ul>
1992 </div>
1993 <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>
1994 <?php else: ?>
1995 <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>
1996 <?php endif; ?>
1997 </div>
1998
1999</form>
2000
2001<?php
2002fm_show_footer();
2003
2004//--- END
2005
2006// Functions
2007
2008/**
2009 * Check if the filename is allowed.
2010 * @param string $filename
2011 * @return bool
2012 */
2013function fm_is_file_allowed($filename)
2014{
2015 // By default, no file is allowed
2016 $allowed = false;
2017
2018 if (FM_EXTENSION) {
2019 $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
2020
2021 if (in_array($ext, explode(',', strtolower(FM_EXTENSION)))) {
2022 $allowed = true;
2023 }
2024 }
2025
2026 return $allowed;
2027}
2028
2029/**
2030 * Delete file or folder (recursively)
2031 * @param string $path
2032 * @return bool
2033 */
2034function fm_rdelete($path)
2035{
2036 if (is_link($path)) {
2037 return unlink($path);
2038 } elseif (is_dir($path)) {
2039 $objects = scandir($path);
2040 $ok = true;
2041 if (is_array($objects)) {
2042 foreach ($objects as $file) {
2043 if ($file != '.' && $file != '..') {
2044 if (!fm_rdelete($path . '/' . $file)) {
2045 $ok = false;
2046 }
2047 }
2048 }
2049 }
2050 return ($ok) ? rmdir($path) : false;
2051 } elseif (is_file($path)) {
2052 return unlink($path);
2053 }
2054 return false;
2055}
2056
2057/**
2058 * Recursive chmod
2059 * @param string $path
2060 * @param int $filemode
2061 * @param int $dirmode
2062 * @return bool
2063 * @todo Will use in mass chmod
2064 */
2065function fm_rchmod($path, $filemode, $dirmode)
2066{
2067 if (is_dir($path)) {
2068 if (!chmod($path, $dirmode)) {
2069 return false;
2070 }
2071 $objects = scandir($path);
2072 if (is_array($objects)) {
2073 foreach ($objects as $file) {
2074 if ($file != '.' && $file != '..') {
2075 if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) {
2076 return false;
2077 }
2078 }
2079 }
2080 }
2081 return true;
2082 } elseif (is_link($path)) {
2083 return true;
2084 } elseif (is_file($path)) {
2085 return chmod($path, $filemode);
2086 }
2087 return false;
2088}
2089
2090/**
2091 * Check the file extension which is allowed or not
2092 * @param string $filename
2093 * @return bool
2094 */
2095function fm_is_valid_ext($filename)
2096{
2097 $allowed = (FM_FILE_EXTENSION) ? explode(',', FM_FILE_EXTENSION) : false;
2098
2099 $ext = pathinfo($filename, PATHINFO_EXTENSION);
2100 $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;
2101
2102 return ($isFileAllowed) ? true : false;
2103}
2104
2105/**
2106 * Safely rename
2107 * @param string $old
2108 * @param string $new
2109 * @return bool|null
2110 */
2111function fm_rename($old, $new)
2112{
2113 $isFileAllowed = fm_is_valid_ext($new);
2114
2115 if(!$isFileAllowed) return false;
2116
2117 return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null;
2118}
2119
2120/**
2121 * Copy file or folder (recursively).
2122 * @param string $path
2123 * @param string $dest
2124 * @param bool $upd Update files
2125 * @param bool $force Create folder with same names instead file
2126 * @return bool
2127 */
2128function fm_rcopy($path, $dest, $upd = true, $force = true)
2129{
2130 if (is_dir($path)) {
2131 if (!fm_mkdir($dest, $force)) {
2132 return false;
2133 }
2134 $objects = scandir($path);
2135 $ok = true;
2136 if (is_array($objects)) {
2137 foreach ($objects as $file) {
2138 if ($file != '.' && $file != '..') {
2139 if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) {
2140 $ok = false;
2141 }
2142 }
2143 }
2144 }
2145 return $ok;
2146 } elseif (is_file($path)) {
2147 return fm_copy($path, $dest, $upd);
2148 }
2149 return false;
2150}
2151
2152/**
2153 * Safely create folder
2154 * @param string $dir
2155 * @param bool $force
2156 * @return bool
2157 */
2158function fm_mkdir($dir, $force)
2159{
2160 if (file_exists($dir)) {
2161 if (is_dir($dir)) {
2162 return $dir;
2163 } elseif (!$force) {
2164 return false;
2165 }
2166 unlink($dir);
2167 }
2168 return mkdir($dir, 0777, true);
2169}
2170
2171/**
2172 * Safely copy file
2173 * @param string $f1
2174 * @param string $f2
2175 * @param bool $upd
2176 * @return bool
2177 */
2178function fm_copy($f1, $f2, $upd)
2179{
2180 $time1 = filemtime($f1);
2181 if (file_exists($f2)) {
2182 $time2 = filemtime($f2);
2183 if ($time2 >= $time1 && $upd) {
2184 return false;
2185 }
2186 }
2187 $ok = copy($f1, $f2);
2188 if ($ok) {
2189 touch($f2, $time1);
2190 }
2191 return $ok;
2192}
2193
2194/**
2195 * Get mime type
2196 * @param string $file_path
2197 * @return mixed|string
2198 */
2199function fm_get_mime_type($file_path)
2200{
2201 if (function_exists('finfo_open')) {
2202 $finfo = finfo_open(FILEINFO_MIME_TYPE);
2203 $mime = finfo_file($finfo, $file_path);
2204 finfo_close($finfo);
2205 return $mime;
2206 } elseif (function_exists('mime_content_type')) {
2207 return mime_content_type($file_path);
2208 } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) {
2209 $file = escapeshellarg($file_path);
2210 $mime = shell_exec('file -bi ' . $file);
2211 return $mime;
2212 } else {
2213 return '--';
2214 }
2215}
2216
2217/**
2218 * HTTP Redirect
2219 * @param string $url
2220 * @param int $code
2221 */
2222function fm_redirect($url, $code = 302)
2223{
2224 header('Location: ' . $url, true, $code);
2225 exit;
2226}
2227
2228/**
2229 * Path traversal prevention and clean the url
2230 * It replaces (consecutive) occurrences of / and \\ with whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine.
2231 * @param $path
2232 * @return string
2233 */
2234function get_absolute_path($path) {
2235 $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
2236 $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
2237 $absolutes = array();
2238 foreach ($parts as $part) {
2239 if ('.' == $part) continue;
2240 if ('..' == $part) {
2241 array_pop($absolutes);
2242 } else {
2243 $absolutes[] = $part;
2244 }
2245 }
2246 return implode(DIRECTORY_SEPARATOR, $absolutes);
2247}
2248
2249/**
2250 * Clean path
2251 * @param string $path
2252 * @return string
2253 */
2254function fm_clean_path($path, $trim = true)
2255{
2256 $path = $trim ? trim($path) : $path;
2257 $path = trim($path, '\\/');
2258 $path = str_replace(array('../', '..\\'), '', $path);
2259 $path = get_absolute_path($path);
2260 if ($path == '..') {
2261 $path = '';
2262 }
2263 return str_replace('\\', '/', $path);
2264}
2265
2266/**
2267 * Get parent path
2268 * @param string $path
2269 * @return bool|string
2270 */
2271function fm_get_parent_path($path)
2272{
2273 $path = fm_clean_path($path);
2274 if ($path != '') {
2275 $array = explode('/', $path);
2276 if (count($array) > 1) {
2277 $array = array_slice($array, 0, -1);
2278 return implode('/', $array);
2279 }
2280 return '';
2281 }
2282 return false;
2283}
2284
2285/**
2286 * Check file is in exclude list
2287 * @param string $file
2288 * @return bool
2289 */
2290function fm_is_exclude_items($file) {
2291 $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
2292 if(!in_array($file, FM_EXCLUDE_ITEMS) && !in_array("*.$ext", FM_EXCLUDE_ITEMS)) {
2293 return true;
2294 }
2295 return false;
2296}
2297
2298/**
2299 * get language translations from json file
2300 * @param int $tr
2301 * @return array
2302 */
2303function fm_get_translations($tr) {
2304 try {
2305 $content = @file_get_contents('translation.json');
2306 if($content !== FALSE) {
2307 $lng = json_decode($content, TRUE);
2308 global $lang_list;
2309 foreach ($lng["language"] as $key => $value)
2310 {
2311 $code = $value["code"];
2312 $lang_list[$code] = $value["name"];
2313 if ($tr)
2314 $tr[$code] = $value["translation"];
2315 }
2316 return $tr;
2317 }
2318
2319 }
2320 catch (Exception $e) {
2321 echo $e;
2322 }
2323}
2324
2325/**
2326 * @param $file
2327 * Recover all file sizes larger than > 2GB.
2328 * Works on php 32bits and 64bits and supports linux
2329 * @return int|string
2330 */
2331function fm_get_size($file)
2332{
2333 static $iswin;
2334 static $isdarwin;
2335 if (!isset($iswin)) {
2336 $iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
2337 }
2338 if (!isset($isdarwin)) {
2339 $isdarwin = (strtoupper(substr(PHP_OS, 0)) == "DARWIN");
2340 }
2341
2342 static $exec_works;
2343 if (!isset($exec_works)) {
2344 $exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC');
2345 }
2346
2347 // try a shell command
2348 if ($exec_works) {
2349 $arg = escapeshellarg($file);
2350 $cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg");
2351 @exec($cmd, $output);
2352 if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) {
2353 return $size;
2354 }
2355 }
2356
2357 // try the Windows COM interface
2358 if ($iswin && class_exists("COM")) {
2359 try {
2360 $fsobj = new COM('Scripting.FileSystemObject');
2361 $f = $fsobj->GetFile( realpath($file) );
2362 $size = $f->Size;
2363 } catch (Exception $e) {
2364 $size = null;
2365 }
2366 if (ctype_digit($size)) {
2367 return $size;
2368 }
2369 }
2370
2371 // if all else fails
2372 return filesize($file);
2373}
2374
2375/**
2376 * Get nice filesize
2377 * @param int $size
2378 * @return string
2379 */
2380function fm_get_filesize($size)
2381{
2382 if ($size < 1000) {
2383 return sprintf('%s B', $size);
2384 } elseif (($size / 1024) < 1000) {
2385 return sprintf('%s KB', round(($size / 1024), 2));
2386 } elseif (($size / 1024 / 1024) < 1000) {
2387 return sprintf('%s MB', round(($size / 1024 / 1024), 2));
2388 } elseif (($size / 1024 / 1024 / 1024) < 1000) {
2389 return sprintf('%s GB', round(($size / 1024 / 1024 / 1024), 2));
2390 } else {
2391 return sprintf('%s TB', round(($size / 1024 / 1024 / 1024 / 1024), 2));
2392 }
2393}
2394
2395/**
2396 * Get director total size
2397 * @param string $directory
2398 * @return string
2399 */
2400function fm_get_directorysize($directory) {
2401 global $calc_folder;
2402 if ($calc_folder==true) { // Slower output
2403 $size = 0; $count= 0; $dirCount= 0;
2404 foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file)
2405 if ($file->isFile())
2406 { $size+=$file->getSize();
2407 $count++;
2408 }
2409 else if ($file->isDir()) { $dirCount++; }
2410 // return [$size, $count, $dirCount];
2411 return fm_get_filesize($size);
2412 }
2413 else return 'Folder'; // Quick output
2414}
2415
2416/**
2417 * Get info about zip archive
2418 * @param string $path
2419 * @return array|bool
2420 */
2421function fm_get_zif_info($path, $ext) {
2422 if ($ext == 'zip' && function_exists('zip_open')) {
2423 $arch = zip_open($path);
2424 if ($arch) {
2425 $filenames = array();
2426 while ($zip_entry = zip_read($arch)) {
2427 $zip_name = zip_entry_name($zip_entry);
2428 $zip_folder = substr($zip_name, -1) == '/';
2429 $filenames[] = array(
2430 'name' => $zip_name,
2431 'filesize' => zip_entry_filesize($zip_entry),
2432 'compressed_size' => zip_entry_compressedsize($zip_entry),
2433 'folder' => $zip_folder
2434 //'compression_method' => zip_entry_compressionmethod($zip_entry),
2435 );
2436 }
2437 zip_close($arch);
2438 return $filenames;
2439 }
2440 } elseif($ext == 'tar' && class_exists('PharData')) {
2441 $archive = new PharData($path);
2442 $filenames = array();
2443 foreach(new RecursiveIteratorIterator($archive) as $file) {
2444 $parent_info = $file->getPathInfo();
2445 $zip_name = str_replace("phar://".$path, '', $file->getPathName());
2446 $zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0);
2447 $zip_folder = $parent_info->getFileName();
2448 $zip_info = new SplFileInfo($file);
2449 $filenames[] = array(
2450 'name' => $zip_name,
2451 'filesize' => $zip_info->getSize(),
2452 'compressed_size' => $file->getCompressedSize(),
2453 'folder' => $zip_folder
2454 );
2455 }
2456 return $filenames;
2457 }
2458 return false;
2459}
2460
2461/**
2462 * Encode html entities
2463 * @param string $text
2464 * @return string
2465 */
2466function fm_enc($text)
2467{
2468 return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
2469}
2470
2471/**
2472 * Prevent XSS attacks
2473 * @param string $text
2474 * @return string
2475 */
2476function fm_isvalid_filename($text) {
2477 return (strpbrk($text, '/?%*:|"<>') === FALSE) ? true : false;
2478}
2479
2480/**
2481 * Save message in session
2482 * @param string $msg
2483 * @param string $status
2484 */
2485function fm_set_msg($msg, $status = 'ok')
2486{
2487 $_SESSION[FM_SESSION_ID]['message'] = $msg;
2488 $_SESSION[FM_SESSION_ID]['status'] = $status;
2489}
2490
2491/**
2492 * Check if string is in UTF-8
2493 * @param string $string
2494 * @return int
2495 */
2496function fm_is_utf8($string)
2497{
2498 return preg_match('//u', $string);
2499}
2500
2501/**
2502 * Convert file name to UTF-8 in Windows
2503 * @param string $filename
2504 * @return string
2505 */
2506function fm_convert_win($filename)
2507{
2508 if (FM_IS_WIN && function_exists('iconv')) {
2509 $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename);
2510 }
2511 return $filename;
2512}
2513
2514/**
2515 * @param $obj
2516 * @return array
2517 */
2518function fm_object_to_array($obj)
2519{
2520 if (!is_object($obj) && !is_array($obj)) {
2521 return $obj;
2522 }
2523 if (is_object($obj)) {
2524 $obj = get_object_vars($obj);
2525 }
2526 return array_map('fm_object_to_array', $obj);
2527}
2528
2529/**
2530 * Get CSS classname for file
2531 * @param string $path
2532 * @return string
2533 */
2534function fm_get_file_icon_class($path)
2535{
2536 // get extension
2537 $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
2538
2539 switch ($ext) {
2540 case 'ico':
2541 case 'gif':
2542 case 'jpg':
2543 case 'jpeg':
2544 case 'jpc':
2545 case 'jp2':
2546 case 'jpx':
2547 case 'xbm':
2548 case 'wbmp':
2549 case 'png':
2550 case 'bmp':
2551 case 'tif':
2552 case 'tiff':
2553 case 'svg':
2554 $img = 'fa fa-picture-o';
2555 break;
2556 case 'passwd':
2557 case 'ftpquota':
2558 case 'sql':
2559 case 'js':
2560 case 'json':
2561 case 'sh':
2562 case 'config':
2563 case 'twig':
2564 case 'tpl':
2565 case 'md':
2566 case 'gitignore':
2567 case 'c':
2568 case 'cpp':
2569 case 'cs':
2570 case 'py':
2571 case 'map':
2572 case 'lock':
2573 case 'dtd':
2574 $img = 'fa fa-file-code-o';
2575 break;
2576 case 'txt':
2577 case 'ini':
2578 case 'conf':
2579 case 'log':
2580 case 'htaccess':
2581 $img = 'fa fa-file-text-o';
2582 break;
2583 case 'css':
2584 case 'less':
2585 case 'sass':
2586 case 'scss':
2587 $img = 'fa fa-css3';
2588 break;
2589 case 'zip':
2590 case 'rar':
2591 case 'gz':
2592 case 'tar':
2593 case '7z':
2594 $img = 'fa fa-file-archive-o';
2595 break;
2596 case 'php':
2597 case 'php4':
2598 case 'php5':
2599 case 'phps':
2600 case 'phtml':
2601 $img = 'fa fa-code';
2602 break;
2603 case 'htm':
2604 case 'html':
2605 case 'shtml':
2606 case 'xhtml':
2607 $img = 'fa fa-html5';
2608 break;
2609 case 'xml':
2610 case 'xsl':
2611 $img = 'fa fa-file-excel-o';
2612 break;
2613 case 'wav':
2614 case 'mp3':
2615 case 'mp2':
2616 case 'm4a':
2617 case 'aac':
2618 case 'ogg':
2619 case 'oga':
2620 case 'wma':
2621 case 'mka':
2622 case 'flac':
2623 case 'ac3':
2624 case 'tds':
2625 $img = 'fa fa-music';
2626 break;
2627 case 'm3u':
2628 case 'm3u8':
2629 case 'pls':
2630 case 'cue':
2631 $img = 'fa fa-headphones';
2632 break;
2633 case 'avi':
2634 case 'mpg':
2635 case 'mpeg':
2636 case 'mp4':
2637 case 'm4v':
2638 case 'flv':
2639 case 'f4v':
2640 case 'ogm':
2641 case 'ogv':
2642 case 'mov':
2643 case 'mkv':
2644 case '3gp':
2645 case 'asf':
2646 case 'wmv':
2647 $img = 'fa fa-file-video-o';
2648 break;
2649 case 'eml':
2650 case 'msg':
2651 $img = 'fa fa-envelope-o';
2652 break;
2653 case 'xls':
2654 case 'xlsx':
2655 case 'ods':
2656 $img = 'fa fa-file-excel-o';
2657 break;
2658 case 'csv':
2659 $img = 'fa fa-file-text-o';
2660 break;
2661 case 'bak':
2662 $img = 'fa fa-clipboard';
2663 break;
2664 case 'doc':
2665 case 'docx':
2666 case 'odt':
2667 $img = 'fa fa-file-word-o';
2668 break;
2669 case 'ppt':
2670 case 'pptx':
2671 $img = 'fa fa-file-powerpoint-o';
2672 break;
2673 case 'ttf':
2674 case 'ttc':
2675 case 'otf':
2676 case 'woff':
2677 case 'woff2':
2678 case 'eot':
2679 case 'fon':
2680 $img = 'fa fa-font';
2681 break;
2682 case 'pdf':
2683 $img = 'fa fa-file-pdf-o';
2684 break;
2685 case 'psd':
2686 case 'ai':
2687 case 'eps':
2688 case 'fla':
2689 case 'swf':
2690 $img = 'fa fa-file-image-o';
2691 break;
2692 case 'exe':
2693 case 'msi':
2694 $img = 'fa fa-file-o';
2695 break;
2696 case 'bat':
2697 $img = 'fa fa-terminal';
2698 break;
2699 default:
2700 $img = 'fa fa-info-circle';
2701 }
2702
2703 return $img;
2704}
2705
2706/**
2707 * Get image files extensions
2708 * @return array
2709 */
2710function fm_get_image_exts()
2711{
2712 return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg');
2713}
2714
2715/**
2716 * Get video files extensions
2717 * @return array
2718 */
2719function fm_get_video_exts()
2720{
2721 return array('avi', 'webm', 'wmv', 'mp4', 'm4v', 'ogm', 'ogv', 'mov', 'mkv');
2722}
2723
2724/**
2725 * Get audio files extensions
2726 * @return array
2727 */
2728function fm_get_audio_exts()
2729{
2730 return array('wav', 'mp3', 'ogg', 'm4a');
2731}
2732
2733/**
2734 * Get text file extensions
2735 * @return array
2736 */
2737function fm_get_text_exts()
2738{
2739 return array(
2740 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'json', 'sh', 'config',
2741 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue',
2742 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py',
2743 'map', 'lock', 'dtd', 'svg', 'scss', 'asp', 'aspx', 'asx', 'asmx', 'ashx', 'jsx', 'jsp', 'jspx', 'cfm', 'cgi'
2744 );
2745}
2746
2747/**
2748 * Get mime types of text files
2749 * @return array
2750 */
2751function fm_get_text_mimes()
2752{
2753 return array(
2754 'application/xml',
2755 'application/javascript',
2756 'application/x-javascript',
2757 'image/svg+xml',
2758 'message/rfc822',
2759 );
2760}
2761
2762/**
2763 * Get file names of text files w/o extensions
2764 * @return array
2765 */
2766function fm_get_text_names()
2767{
2768 return array(
2769 'license',
2770 'readme',
2771 'authors',
2772 'contributors',
2773 'changelog',
2774 );
2775}
2776
2777/**
2778 * Get online docs viewer supported files extensions
2779 * @return array
2780 */
2781function fm_get_onlineViewer_exts()
2782{
2783 return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar', 'odt', 'ods');
2784}
2785
2786/**
2787 * This function scans the files and folder recursively, and return matching files
2788 * @param string $dir
2789 * @return json
2790 */
2791 function scan($dir, $filter = '') {
2792 $path = FM_ROOT_PATH.'/'.$dir;
2793 $ite = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
2794 $rii = new RegexIterator($ite, "/(".$filter.")/i");
2795
2796 $files = array();
2797 foreach ($rii as $file) {
2798 if (!$file->isDir()) {
2799 $fileName = $file->getFilename();
2800 $location = str_replace(FM_ROOT_PATH, '', $file->getPath());
2801 $files[] = array(
2802 "name" => $fileName,
2803 "type" => "file",
2804 "path" => $location,
2805 );
2806 }
2807 }
2808 return $files;
2809}
2810
2811/**
2812 * Class to work with zip files (using ZipArchive)
2813 */
2814class FM_Zipper
2815{
2816 private $zip;
2817
2818 public function __construct()
2819 {
2820 $this->zip = new ZipArchive();
2821 }
2822
2823 /**
2824 * Create archive with name $filename and files $files (RELATIVE PATHS!)
2825 * @param string $filename
2826 * @param array|string $files
2827 * @return bool
2828 */
2829 public function create($filename, $files)
2830 {
2831 $res = $this->zip->open($filename, ZipArchive::CREATE);
2832 if ($res !== true) {
2833 return false;
2834 }
2835 if (is_array($files)) {
2836 foreach ($files as $f) {
2837 if (!$this->addFileOrDir($f)) {
2838 $this->zip->close();
2839 return false;
2840 }
2841 }
2842 $this->zip->close();
2843 return true;
2844 } else {
2845 if ($this->addFileOrDir($files)) {
2846 $this->zip->close();
2847 return true;
2848 }
2849 return false;
2850 }
2851 }
2852
2853 /**
2854 * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS)
2855 * @param string $filename
2856 * @param string $path
2857 * @return bool
2858 */
2859 public function unzip($filename, $path)
2860 {
2861 $res = $this->zip->open($filename);
2862 if ($res !== true) {
2863 return false;
2864 }
2865 if ($this->zip->extractTo($path)) {
2866 $this->zip->close();
2867 return true;
2868 }
2869 return false;
2870 }
2871
2872 /**
2873 * Add file/folder to archive
2874 * @param string $filename
2875 * @return bool
2876 */
2877 private function addFileOrDir($filename)
2878 {
2879 if (is_file($filename)) {
2880 return $this->zip->addFile($filename);
2881 } elseif (is_dir($filename)) {
2882 return $this->addDir($filename);
2883 }
2884 return false;
2885 }
2886
2887 /**
2888 * Add folder recursively
2889 * @param string $path
2890 * @return bool
2891 */
2892 private function addDir($path)
2893 {
2894 if (!$this->zip->addEmptyDir($path)) {
2895 return false;
2896 }
2897 $objects = scandir($path);
2898 if (is_array($objects)) {
2899 foreach ($objects as $file) {
2900 if ($file != '.' && $file != '..') {
2901 if (is_dir($path . '/' . $file)) {
2902 if (!$this->addDir($path . '/' . $file)) {
2903 return false;
2904 }
2905 } elseif (is_file($path . '/' . $file)) {
2906 if (!$this->zip->addFile($path . '/' . $file)) {
2907 return false;
2908 }
2909 }
2910 }
2911 }
2912 return true;
2913 }
2914 return false;
2915 }
2916}
2917
2918/**
2919 * Class to work with Tar files (using PharData)
2920 */
2921class FM_Zipper_Tar
2922{
2923 private $tar;
2924
2925 public function __construct()
2926 {
2927 $this->tar = null;
2928 }
2929
2930 /**
2931 * Create archive with name $filename and files $files (RELATIVE PATHS!)
2932 * @param string $filename
2933 * @param array|string $files
2934 * @return bool
2935 */
2936 public function create($filename, $files)
2937 {
2938 $this->tar = new PharData($filename);
2939 if (is_array($files)) {
2940 foreach ($files as $f) {
2941 if (!$this->addFileOrDir($f)) {
2942 return false;
2943 }
2944 }
2945 return true;
2946 } else {
2947 if ($this->addFileOrDir($files)) {
2948 return true;
2949 }
2950 return false;
2951 }
2952 }
2953
2954 /**
2955 * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS)
2956 * @param string $filename
2957 * @param string $path
2958 * @return bool
2959 */
2960 public function unzip($filename, $path)
2961 {
2962 $res = $this->tar->open($filename);
2963 if ($res !== true) {
2964 return false;
2965 }
2966 if ($this->tar->extractTo($path)) {
2967 return true;
2968 }
2969 return false;
2970 }
2971
2972 /**
2973 * Add file/folder to archive
2974 * @param string $filename
2975 * @return bool
2976 */
2977 private function addFileOrDir($filename)
2978 {
2979 if (is_file($filename)) {
2980 try {
2981 $this->tar->addFile($filename);
2982 return true;
2983 } catch (Exception $e) {
2984 return false;
2985 }
2986 } elseif (is_dir($filename)) {
2987 return $this->addDir($filename);
2988 }
2989 return false;
2990 }
2991
2992 /**
2993 * Add folder recursively
2994 * @param string $path
2995 * @return bool
2996 */
2997 private function addDir($path)
2998 {
2999 $objects = scandir($path);
3000 if (is_array($objects)) {
3001 foreach ($objects as $file) {
3002 if ($file != '.' && $file != '..') {
3003 if (is_dir($path . '/' . $file)) {
3004 if (!$this->addDir($path . '/' . $file)) {
3005 return false;
3006 }
3007 } elseif (is_file($path . '/' . $file)) {
3008 try {
3009 $this->tar->addFile($path . '/' . $file);
3010 } catch (Exception $e) {
3011 return false;
3012 }
3013 }
3014 }
3015 }
3016 return true;
3017 }
3018 return false;
3019 }
3020}
3021
3022
3023
3024/**
3025 * Save Configuration
3026 */
3027 class FM_Config
3028{
3029 var $data;
3030
3031 function __construct()
3032 {
3033 global $root_path, $root_url, $CONFIG;
3034 $fm_url = $root_url.$_SERVER["PHP_SELF"];
3035 $this->data = array(
3036 'lang' => 'en',
3037 'error_reporting' => true,
3038 'show_hidden' => true
3039 );
3040 $data = false;
3041 if (strlen($CONFIG)) {
3042 $data = fm_object_to_array(json_decode($CONFIG));
3043 } else {
3044 $msg = 'Tiny File Manager<br>Error: Cannot load configuration';
3045 if (substr($fm_url, -1) == '/') {
3046 $fm_url = rtrim($fm_url, '/');
3047 $msg .= '<br>';
3048 $msg .= '<br>Seems like you have a trailing slash on the URL.';
3049 $msg .= '<br>Try this link: <a href="' . $fm_url . '">' . $fm_url . '</a>';
3050 }
3051 die($msg);
3052 }
3053 if (is_array($data) && count($data)) $this->data = $data;
3054 else $this->save();
3055 }
3056
3057 function save()
3058 {
3059 global $root_path;
3060 $fm_file = $root_path.$_SERVER["PHP_SELF"];
3061 $var_name = '$CONFIG';
3062 $var_value = var_export(json_encode($this->data), true);
3063 $config_string = "<?php" . chr(13) . chr(10) . "//Default Configuration".chr(13) . chr(10)."$var_name = $var_value;" . chr(13) . chr(10);
3064 if (file_exists($fm_file)) {
3065 $lines = file($fm_file);
3066 if ($fh = @fopen($fm_file, "w")) {
3067 @fputs($fh, $config_string, strlen($config_string));
3068 for ($x = 3; $x < count($lines); $x++) {
3069 @fputs($fh, $lines[$x], strlen($lines[$x]));
3070 }
3071 @fclose($fh);
3072 }
3073 }
3074 }
3075}
3076
3077
3078
3079//--- templates functions
3080
3081/**
3082 * Show nav block
3083 * @param string $path
3084 */
3085function fm_show_nav_path($path)
3086{
3087 global $lang, $sticky_navbar;
3088 $isStickyNavBar = $sticky_navbar ? 'fixed-top' : '';
3089 ?>
3090 <nav class="navbar navbar-expand-lg navbar-light bg-white mb-4 main-nav <?php echo $isStickyNavBar ?>">
3091 <a class="navbar-brand" href=""> <?php echo lng('AppTitle') ?> </a>
3092 <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
3093 <span class="navbar-toggler-icon"></span>
3094 </button>
3095 <div class="collapse navbar-collapse" id="navbarSupportedContent">
3096
3097 <?php
3098 $path = fm_clean_path($path);
3099 $root_url = "<a href='?p='><i class='fa fa-home' aria-hidden='true' title='" . FM_ROOT_PATH . "'></i></a>";
3100 $sep = '<i class="bread-crumb"> / </i>';
3101 if ($path != '') {
3102 $exploded = explode('/', $path);
3103 $count = count($exploded);
3104 $array = array();
3105 $parent = '';
3106 for ($i = 0; $i < $count; $i++) {
3107 $parent = trim($parent . '/' . $exploded[$i], '/');
3108 $parent_enc = urlencode($parent);
3109 $array[] = "<a href='?p={$parent_enc}'>" . fm_enc(fm_convert_win($exploded[$i])) . "</a>";
3110 }
3111 $root_url .= $sep . implode($sep, $array);
3112 }
3113 echo '<div class="col-xs-6 col-sm-5">' . $root_url . '</div>';
3114 ?>
3115
3116 <div class="col-xs-6 col-sm-7 text-right">
3117 <ul class="navbar-nav mr-auto float-right">
3118 <li class="nav-item mr-2">
3119 <div class="input-group input-group-sm mr-1" style="margin-top:4px;">
3120 <input type="text" class="form-control" placeholder="<?php echo lng('Search') ?>" aria-label="<?php echo lng('Search') ?>" aria-describedby="search-addon2" id="search-addon">
3121 <div class="input-group-append btn-group">
3122 <span class="input-group-text dropdown-toggle" id="search-addon2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
3123 <div class="dropdown-menu dropdown-menu-right">
3124 <a class="dropdown-item" href="<?php echo $path2 = $path ? $path : '.'; ?>" id="js-search-modal" data-toggle="modal" data-target="#searchModal">Advanced Search</a>
3125 </div>
3126 </div>
3127 </div>
3128 </li>
3129 <?php if (!FM_READONLY): ?>
3130 <li class="nav-item">
3131 <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>
3132 </li>
3133 <li class="nav-item">
3134 <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>
3135 </li>
3136 <?php endif; ?>
3137 <?php if (FM_USE_AUTH): ?>
3138 <li class="nav-item avatar dropdown">
3139 <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>
3140 <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink-5">
3141 <?php if (!FM_READONLY): ?>
3142 <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>
3143 <?php endif ?>
3144 <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>
3145 <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>
3146 </div>
3147 </li>
3148 <?php else: ?>
3149 <?php if (!FM_READONLY): ?>
3150 <li class="nav-item">
3151 <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>
3152 </li>
3153 <?php endif; ?>
3154 <?php endif; ?>
3155 </ul>
3156 </div>
3157 </div>
3158 </nav>
3159 <?php
3160}
3161
3162/**
3163 * Show message from session
3164 */
3165function fm_show_message()
3166{
3167 if (isset($_SESSION[FM_SESSION_ID]['message'])) {
3168 $class = isset($_SESSION[FM_SESSION_ID]['status']) ? $_SESSION[FM_SESSION_ID]['status'] : 'ok';
3169 echo '<p class="message ' . $class . '">' . $_SESSION[FM_SESSION_ID]['message'] . '</p>';
3170 unset($_SESSION[FM_SESSION_ID]['message']);
3171 unset($_SESSION[FM_SESSION_ID]['status']);
3172 }
3173}
3174
3175/**
3176 * Show page header in Login Form
3177 */
3178function fm_show_header_login()
3179{
3180$sprites_ver = '20160315';
3181header("Content-Type: text/html; charset=utf-8");
3182header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
3183header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
3184header("Pragma: no-cache");
3185
3186global $lang, $root_url, $favicon_path;
3187?>
3188<!DOCTYPE html>
3189<html lang="en">
3190<head>
3191 <meta charset="utf-8">
3192 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
3193 <meta name="description" content="Web based File Manager in PHP, Manage your files efficiently and easily with Tiny File Manager">
3194 <meta name="author" content="CCP Programmers">
3195 <meta name="robots" content="noindex, nofollow">
3196 <meta name="googlebot" content="noindex">
3197 <link rel="icon" href="<?php echo fm_enc($favicon_path) ?>" type="image/png">
3198 <title><?php echo fm_enc(APP_TITLE) ?></title>
3199 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
3200 <style>
3201 body.fm-login-page{ background-color:#f7f9fb;font-size:14px;background-color:#f7f9fb;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 304 304' width='304' height='304'%3E%3Cpath fill='%23e2e9f1' fill-opacity='0.4' d='M44.1 224a5 5 0 1 1 0 2H0v-2h44.1zm160 48a5 5 0 1 1 0 2H82v-2h122.1zm57.8-46a5 5 0 1 1 0-2H304v2h-42.1zm0 16a5 5 0 1 1 0-2H304v2h-42.1zm6.2-114a5 5 0 1 1 0 2h-86.2a5 5 0 1 1 0-2h86.2zm-256-48a5 5 0 1 1 0 2H0v-2h12.1zm185.8 34a5 5 0 1 1 0-2h86.2a5 5 0 1 1 0 2h-86.2zM258 12.1a5 5 0 1 1-2 0V0h2v12.1zm-64 208a5 5 0 1 1-2 0v-54.2a5 5 0 1 1 2 0v54.2zm48-198.2V80h62v2h-64V21.9a5 5 0 1 1 2 0zm16 16V64h46v2h-48V37.9a5 5 0 1 1 2 0zm-128 96V208h16v12.1a5 5 0 1 1-2 0V210h-16v-76.1a5 5 0 1 1 2 0zm-5.9-21.9a5 5 0 1 1 0 2H114v48H85.9a5 5 0 1 1 0-2H112v-48h12.1zm-6.2 130a5 5 0 1 1 0-2H176v-74.1a5 5 0 1 1 2 0V242h-60.1zm-16-64a5 5 0 1 1 0-2H114v48h10.1a5 5 0 1 1 0 2H112v-48h-10.1zM66 284.1a5 5 0 1 1-2 0V274H50v30h-2v-32h18v12.1zM236.1 176a5 5 0 1 1 0 2H226v94h48v32h-2v-30h-48v-98h12.1zm25.8-30a5 5 0 1 1 0-2H274v44.1a5 5 0 1 1-2 0V146h-10.1zm-64 96a5 5 0 1 1 0-2H208v-80h16v-14h-42.1a5 5 0 1 1 0-2H226v18h-16v80h-12.1zm86.2-210a5 5 0 1 1 0 2H272V0h2v32h10.1zM98 101.9V146H53.9a5 5 0 1 1 0-2H96v-42.1a5 5 0 1 1 2 0zM53.9 34a5 5 0 1 1 0-2H80V0h2v34H53.9zm60.1 3.9V66H82v64H69.9a5 5 0 1 1 0-2H80V64h32V37.9a5 5 0 1 1 2 0zM101.9 82a5 5 0 1 1 0-2H128V37.9a5 5 0 1 1 2 0V82h-28.1zm16-64a5 5 0 1 1 0-2H146v44.1a5 5 0 1 1-2 0V18h-26.1zm102.2 270a5 5 0 1 1 0 2H98v14h-2v-16h124.1zM242 149.9V160h16v34h-16v62h48v48h-2v-46h-48v-66h16v-30h-16v-12.1a5 5 0 1 1 2 0zM53.9 18a5 5 0 1 1 0-2H64V2H48V0h18v18H53.9zm112 32a5 5 0 1 1 0-2H192V0h50v2h-48v48h-28.1zm-48-48a5 5 0 0 1-9.8-2h2.07a3 3 0 1 0 5.66 0H178v34h-18V21.9a5 5 0 1 1 2 0V32h14V2h-58.1zm0 96a5 5 0 1 1 0-2H137l32-32h39V21.9a5 5 0 1 1 2 0V66h-40.17l-32 32H117.9zm28.1 90.1a5 5 0 1 1-2 0v-76.51L175.59 80H224V21.9a5 5 0 1 1 2 0V82h-49.59L146 112.41v75.69zm16 32a5 5 0 1 1-2 0v-99.51L184.59 96H300.1a5 5 0 0 1 3.9-3.9v2.07a3 3 0 0 0 0 5.66v2.07a5 5 0 0 1-3.9-3.9H185.41L162 121.41v98.69zm-144-64a5 5 0 1 1-2 0v-3.51l48-48V48h32V0h2v50H66v55.41l-48 48v2.69zM50 53.9v43.51l-48 48V208h26.1a5 5 0 1 1 0 2H0v-65.41l48-48V53.9a5 5 0 1 1 2 0zm-16 16V89.41l-34 34v-2.82l32-32V69.9a5 5 0 1 1 2 0zM12.1 32a5 5 0 1 1 0 2H9.41L0 43.41V40.6L8.59 32h3.51zm265.8 18a5 5 0 1 1 0-2h18.69l7.41-7.41v2.82L297.41 50H277.9zm-16 160a5 5 0 1 1 0-2H288v-71.41l16-16v2.82l-14 14V210h-28.1zm-208 32a5 5 0 1 1 0-2H64v-22.59L40.59 194H21.9a5 5 0 1 1 0-2H41.41L66 216.59V242H53.9zm150.2 14a5 5 0 1 1 0 2H96v-56.6L56.6 162H37.9a5 5 0 1 1 0-2h19.5L98 200.6V256h106.1zm-150.2 2a5 5 0 1 1 0-2H80v-46.59L48.59 178H21.9a5 5 0 1 1 0-2H49.41L82 208.59V258H53.9zM34 39.8v1.61L9.41 66H0v-2h8.59L32 40.59V0h2v39.8zM2 300.1a5 5 0 0 1 3.9 3.9H3.83A3 3 0 0 0 0 302.17V256h18v48h-2v-46H2v42.1zM34 241v63h-2v-62H0v-2h34v1zM17 18H0v-2h16V0h2v18h-1zm273-2h14v2h-16V0h2v16zm-32 273v15h-2v-14h-14v14h-2v-16h18v1zM0 92.1A5.02 5.02 0 0 1 6 97a5 5 0 0 1-6 4.9v-2.07a3 3 0 1 0 0-5.66V92.1zM80 272h2v32h-2v-32zm37.9 32h-2.07a3 3 0 0 0-5.66 0h-2.07a5 5 0 0 1 9.8 0zM5.9 0A5.02 5.02 0 0 1 0 5.9V3.83A3 3 0 0 0 3.83 0H5.9zm294.2 0h2.07A3 3 0 0 0 304 3.83V5.9a5 5 0 0 1-3.9-5.9zm3.9 300.1v2.07a3 3 0 0 0-1.83 1.83h-2.07a5 5 0 0 1 3.9-3.9zM97 100a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-48 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 96a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-144a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM49 36a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM33 68a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 240a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm80-176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm112 176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 180a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 84a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6z'%3E%3C/path%3E%3C/svg%3E");}
3202 .fm-login-page .brand{ width:121px;overflow:hidden;margin:0 auto;position:relative;z-index:1}
3203 .fm-login-page .brand img{ width:100%}
3204 .fm-login-page .card-wrapper{ width:360px;margin-top:10%;margin-left:auto;margin-right:auto;}
3205 .fm-login-page .card{ border-color:transparent;box-shadow:0 4px 8px rgba(0,0,0,.05)}
3206 .fm-login-page .card-title{ margin-bottom:1.5rem;font-size:24px;font-weight:400;}
3207 .fm-login-page .form-control{ border-width:2.3px}
3208 .fm-login-page .form-group label{ width:100%}
3209 .fm-login-page .btn.btn-block{ padding:12px 10px}
3210 .fm-login-page .footer{ margin:40px 0;color:#888;text-align:center}
3211 @media screen and (max-width:425px){
3212 .fm-login-page .card-wrapper{ width:90%;margin:0 auto;margin-top:10%;}
3213 }
3214 @media screen and (max-width:320px){
3215 .fm-login-page .card.fat{ padding:0}
3216 .fm-login-page .card.fat .card-body{ padding:15px}
3217 }
3218 .message{ padding:4px 7px;border:1px solid #ddd;background-color:#fff}
3219 .message.ok{ border-color:green;color:green}
3220 .message.error{ border-color:red;color:red}
3221 .message.alert{ border-color:orange;color:orange}
3222 </style>
3223</head>
3224<body class="fm-login-page">
3225<div id="wrapper" class="container-fluid">
3226
3227 <?php
3228 }
3229
3230 /**
3231 * Show page footer in Login Form
3232 */
3233 function fm_show_footer_login()
3234 {
3235 ?>
3236</div>
3237<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.slim.min.js"></script>
3238<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
3239</body>
3240</html>
3241<?php
3242}
3243
3244/**
3245 * Show Header after login
3246 */
3247function fm_show_header()
3248{
3249$sprites_ver = '20160315';
3250header("Content-Type: text/html; charset=utf-8");
3251header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
3252header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
3253header("Pragma: no-cache");
3254
3255global $lang, $root_url, $sticky_navbar, $favicon_path;
3256$isStickyNavBar = $sticky_navbar ? 'navbar-fixed' : 'navbar-normal';
3257?>
3258<!DOCTYPE html>
3259<html>
3260<head>
3261 <meta charset="utf-8">
3262 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
3263 <meta name="description" content="Web based File Manager in PHP, Manage your files efficiently and easily with Tiny File Manager">
3264 <meta name="author" content="CCP Programmers">
3265 <meta name="robots" content="noindex, nofollow">
3266 <meta name="googlebot" content="noindex">
3267 <link rel="icon" href="<?php echo fm_enc($favicon_path) ?>" type="image/png">
3268 <title><?php echo fm_enc(APP_TITLE) ?></title>
3269 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
3270 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
3271 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ekko-lightbox/5.3.0/ekko-lightbox.css" />
3272 <?php if (FM_USE_HIGHLIGHTJS): ?>
3273 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/<?php echo FM_HIGHLIGHTJS_STYLE ?>.min.css">
3274 <?php endif; ?>
3275 <style>
3276 body { font-size:14px;color:#222;background:#F7F7F7; }
3277 body.navbar-fixed { margin-top:55px; }
3278 a:hover, a:visited, a:focus { text-decoration:none !important; }
3279 * { -webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important; }
3280 .filename, td, th { white-space:nowrap }
3281 .navbar-brand { font-weight:bold; }
3282 .nav-item.avatar a { cursor:pointer;text-transform:capitalize; }
3283 .nav-item.avatar a > i { font-size:15px; }
3284 .nav-item.avatar .dropdown-menu a { font-size:13px; }
3285 #search-addon { font-size:12px;border-right-width:0; }
3286 #search-addon2 { background:transparent;border-left:0; }
3287 .bread-crumb { color:#cccccc;font-style:normal; }
3288 #main-table .filename a { color:#222222; }
3289 .table td, .table th { vertical-align:middle !important; }
3290 .table .custom-checkbox-td .custom-control.custom-checkbox, .table .custom-checkbox-header .custom-control.custom-checkbox { min-width:18px; }
3291 .table-sm td, .table-sm th { padding:.4rem; }
3292 .table-bordered td, .table-bordered th { border:1px solid #f1f1f1; }
3293 .hidden { display:none }
3294 pre.with-hljs { padding:0 }
3295 pre.with-hljs code { margin:0;border:0;overflow:visible }
3296 code.maxheight, pre.maxheight { max-height:512px }
3297 .fa.fa-caret-right { font-size:1.2em;margin:0 4px;vertical-align:middle;color:#ececec }
3298 .fa.fa-home { font-size:1.3em;vertical-align:bottom }
3299 .path { margin-bottom:10px }
3300 form.dropzone { min-height:200px;border:2px dashed #007bff;line-height:6rem; }
3301 .right { text-align:right }
3302 .center, .close, .login-form { text-align:center }
3303 .message { padding:4px 7px;border:1px solid #ddd;background-color:#fff }
3304 .message.ok { border-color:green;color:green }
3305 .message.error { border-color:red;color:red }
3306 .message.alert { border-color:orange;color:orange }
3307 .preview-img { max-width:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAKklEQVR42mL5//8/Azbw+PFjrOJMDCSCUQ3EABZc4S0rKzsaSvTTABBgAMyfCMsY4B9iAAAAAElFTkSuQmCC) }
3308 .inline-actions > a > i { font-size:1em;margin-left:5px;background:#3785c1;color:#fff;padding:3px;border-radius:3px }
3309 .preview-video { position:relative;max-width:100%;height:0;padding-bottom:62.5%;margin-bottom:10px }
3310 .preview-video video { position:absolute;width:100%;height:100%;left:0;top:0;background:#000 }
3311 .compact-table { border:0;width:auto }
3312 .compact-table td, .compact-table th { width:100px;border:0;text-align:center }
3313 .compact-table tr:hover td { background-color:#fff }
3314 .filename { max-width:420px;overflow:hidden;text-overflow:ellipsis }
3315 .break-word { word-wrap:break-word;margin-left:30px }
3316 .break-word.float-left a { color:#7d7d7d }
3317 .break-word + .float-right { padding-right:30px;position:relative }
3318 .break-word + .float-right > a { color:#7d7d7d;font-size:1.2em;margin-right:4px }
3319 #editor { position:absolute;right:15px;top:100px;bottom:15px;left:15px }
3320 @media (max-width:481px) {
3321 #editor { top:150px; }
3322 }
3323 #normal-editor { border-radius:3px;border-width:2px;padding:10px;outline:none; }
3324 .btn-2 { border-radius:0;padding:3px 6px;font-size:small; }
3325 li.file:before,li.folder:before { font:normal normal normal 14px/1 FontAwesome;content:"\f016";margin-right:5px }
3326 li.folder:before { content:"\f114" }
3327 i.fa.fa-folder-o { color:#0157b3 }
3328 i.fa.fa-picture-o { color:#26b99a }
3329 i.fa.fa-file-archive-o { color:#da7d7d }
3330 .btn-2 i.fa.fa-file-archive-o { color:inherit }
3331 i.fa.fa-css3 { color:#f36fa0 }
3332 i.fa.fa-file-code-o { color:#007bff }
3333 i.fa.fa-code { color:#cc4b4c }
3334 i.fa.fa-file-text-o { color:#0096e6 }
3335 i.fa.fa-html5 { color:#d75e72 }
3336 i.fa.fa-file-excel-o { color:#09c55d }
3337 i.fa.fa-file-powerpoint-o { color:#f6712e }
3338 i.go-back { font-size:1.2em;color:#007bff; }
3339 .main-nav { padding:0.2rem 1rem;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) }
3340 .dataTables_filter { display:none; }
3341 table.dataTable thead .sorting { cursor:pointer;background-repeat:no-repeat;background-position:center right;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7XQMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC'); }
3342 table.dataTable thead .sorting_asc { cursor:pointer;background-repeat:no-repeat;background-position:center right;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg=='); }
3343 table.dataTable thead .sorting_desc { cursor:pointer;background-repeat:no-repeat;background-position:center right;background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII='); }
3344 table.dataTable thead tr:first-child th.custom-checkbox-header:first-child { background-image:none; }
3345 .footer-action li { margin-bottom:10px; }
3346 .app-v-title { font-size:24px;font-weight:300;letter-spacing:-.5px;text-transform:uppercase; }
3347 hr.custom-hr { border-top:1px dashed #8c8b8b;border-bottom:1px dashed #fff; }
3348 .ekko-lightbox .modal-dialog { max-width:98%; }
3349 .ekko-lightbox-item.fade.in.show .row { background:#fff; }
3350 .ekko-lightbox-nav-overlay { display:flex !important;opacity:1 !important;height:auto !important;top:50%; }
3351 .ekko-lightbox-nav-overlay a { opacity:1 !important;width:auto !important;text-shadow:none !important;color:#3B3B3B; }
3352 .ekko-lightbox-nav-overlay a:hover { color:#20507D; }
3353 #snackbar { visibility:hidden;min-width:250px;margin-left:-125px;background-color:#333;color:#fff;text-align:center;border-radius:2px;padding:16px;position:fixed;z-index:1;left:50%;bottom:30px;font-size:17px; }
3354 #snackbar.show { visibility:visible;-webkit-animation:fadein 0.5s, fadeout 0.5s 2.5s;animation:fadein 0.5s, fadeout 0.5s 2.5s; }
3355 @-webkit-keyframes fadein { from { bottom:0;opacity:0; }
3356 to { bottom:30px;opacity:1; }
3357 }
3358 @keyframes fadein { from { bottom:0;opacity:0; }
3359 to { bottom:30px;opacity:1; }
3360 }
3361 @-webkit-keyframes fadeout { from { bottom:30px;opacity:1; }
3362 to { bottom:0;opacity:0; }
3363 }
3364 @keyframes fadeout { from { bottom:30px;opacity:1; }
3365 to { bottom:0;opacity:0; }
3366 }
3367 #main-table span.badge { border-bottom:2px solid #f8f9fa }
3368 #main-table span.badge:nth-child(1) { border-color:#df4227 }
3369 #main-table span.badge:nth-child(2) { border-color:#f8b600 }
3370 #main-table span.badge:nth-child(3) { border-color:#00bd60 }
3371 #main-table span.badge:nth-child(4) { border-color:#4581ff }
3372 #main-table span.badge:nth-child(5) { border-color:#ac68fc }
3373 #main-table span.badge:nth-child(6) { border-color:#45c3d2 }
3374 @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; }
3375 }
3376 .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 }
3377 .lds-facebook { display:none;position:relative;width:64px;height:64px }
3378 .lds-facebook div,.lds-facebook.show-me { display:inline-block }
3379 .lds-facebook div { position:absolute;left:6px;width:13px;background:#007bff;animation:lds-facebook 1.2s cubic-bezier(0,.5,.5,1) infinite }
3380 .lds-facebook div:nth-child(1) { left:6px;animation-delay:-.24s }
3381 .lds-facebook div:nth-child(2) { left:26px;animation-delay:-.12s }
3382 .lds-facebook div:nth-child(3) { left:45px;animation-delay:0 }
3383 @keyframes lds-facebook { 0% { top:6px;height:51px }
3384 100%,50% { top:19px;height:26px }
3385 }
3386 ul#search-wrapper { padding-left: 0;border: 1px solid #ecececcc; } ul#search-wrapper li { list-style: none; padding: 5px;border-bottom: 1px solid #ecececcc; }
3387 ul#search-wrapper li:nth-child(odd){ background: #f9f9f9cc;}
3388 .c-preview-img {
3389 max-width: 300px;
3390 }
3391 </style>
3392</head>
3393<body class="<?php echo $isStickyNavBar; ?>">
3394<div id="wrapper" class="container-fluid">
3395
3396 <!-- New Item creation -->
3397 <div class="modal fade" id="createNewItem" tabindex="-1" role="dialog" aria-label="newItemModalLabel" aria-hidden="true">
3398 <div class="modal-dialog" role="document">
3399 <div class="modal-content">
3400 <div class="modal-header">
3401 <h5 class="modal-title" id="newItemModalLabel"><i class="fa fa-plus-square fa-fw"></i><?php echo lng('CreateNewItem') ?></h5>
3402 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
3403 <span aria-hidden="true">×</span>
3404 </button>
3405 </div>
3406 <div class="modal-body">
3407 <p><label for="newfile"><?php echo lng('ItemType') ?> </label></p>
3408
3409 <div class="custom-control custom-radio custom-control-inline">
3410 <input type="radio" id="customRadioInline1" name="newfile" value="file" class="custom-control-input">
3411 <label class="custom-control-label" for="customRadioInline1"><?php echo lng('File') ?></label>
3412 </div>
3413
3414 <div class="custom-control custom-radio custom-control-inline">
3415 <input type="radio" id="customRadioInline2" name="newfile" value="folder" class="custom-control-input" checked="">
3416 <label class="custom-control-label" for="customRadioInline2"><?php echo lng('Folder') ?></label>
3417 </div>
3418
3419 <p class="mt-3"><label for="newfilename"><?php echo lng('ItemName') ?> </label></p>
3420 <input type="text" name="newfilename" id="newfilename" value="" class="form-control">
3421 </div>
3422 <div class="modal-footer">
3423 <button type="button" class="btn btn-outline-primary" data-dismiss="modal"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></button>
3424 <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>
3425 </div>
3426 </div>
3427 </div>
3428 </div>
3429
3430 <!-- Modal -->
3431 <div class="modal fade" id="searchModal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
3432 <div class="modal-dialog modal-lg" role="document">
3433 <div class="modal-content">
3434 <div class="modal-header">
3435 <h5 class="modal-title col-10" id="searchModalLabel">
3436 <div class="input-group input-group">
3437 <input type="text" class="form-control" placeholder="<?php echo lng('Search') ?> a files" aria-label="<?php echo lng('Search') ?>" aria-describedby="search-addon3" id="advanced-search" autofocus required>
3438 <div class="input-group-append">
3439 <span class="input-group-text" id="search-addon3"><i class="fa fa-search"></i></span>
3440 </div>
3441 </div>
3442 </h5>
3443 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
3444 <span aria-hidden="true">×</span>
3445 </button>
3446 </div>
3447 <div class="modal-body">
3448 <form action="" method="post">
3449 <div class="lds-facebook"><div></div><div></div><div></div></div>
3450 <ul id="search-wrapper">
3451 <p class="m-2">Search file in folder and subfolders...</p>
3452 </ul>
3453 </form>
3454 </div>
3455 </div>
3456 </div>
3457 </div>
3458 <script type="text/html" id="js-tpl-modal">
3459 <div class="modal fade" id="js-ModalCenter-<%this.id%>" tabindex="-1" role="dialog" aria-labelledby="ModalCenterTitle" aria-hidden="true">
3460 <div class="modal-dialog modal-dialog-centered" role="document">
3461 <div class="modal-content">
3462 <div class="modal-header">
3463 <h5 class="modal-title" id="ModalCenterTitle"><%this.title%></h5>
3464 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
3465 <span aria-hidden="true">×</span>
3466 </button>
3467 </div>
3468 <div class="modal-body">
3469 <%this.content%>
3470 </div>
3471 <div class="modal-footer">
3472 <button type="button" class="btn btn-outline-primary" data-dismiss="modal"><i class="fa fa-times-circle"></i> <?php echo lng('Cancel') ?></button>
3473 <%if(this.action){%><button type="button" class="btn btn-primary" id="js-ModalCenterAction" data-type="js-<%this.action%>"><%this.action%></button><%}%>
3474 </div>
3475 </div>
3476 </div>
3477 </div>
3478 </script>
3479
3480 <?php
3481 }
3482
3483 /**
3484 * Show page footer
3485 */
3486 function fm_show_footer()
3487 {
3488 ?>
3489</div>
3490<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
3491<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
3492<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
3493<script src="https://cdnjs.cloudflare.com/ajax/libs/ekko-lightbox/5.3.0/ekko-lightbox.min.js"></script>
3494<?php if (FM_USE_HIGHLIGHTJS): ?>
3495 <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
3496 <script>hljs.initHighlightingOnLoad(); var isHighlightingEnabled = true;</script>
3497<?php endif; ?>
3498<script>
3499 $(document).on('click', '[data-toggle="lightbox"]', function(event) {
3500 event.preventDefault();
3501 var reInitHighlight = function() { if(typeof isHighlightingEnabled !== "undefined" && isHighlightingEnabled) { setTimeout(function () { $('.ekko-lightbox-container pre code').each(function (i, e) { hljs.highlightBlock(e) }); }, 555); } };
3502 $(this).ekkoLightbox({
3503 alwaysShowClose: true, showArrows: true, onShown: function() { reInitHighlight(); }, onNavigate: function(direction, itemIndex) { reInitHighlight(); }
3504 });
3505 });
3506 //TFM Config
3507 window.curi = "https://tinyfilemanager.github.io/config.json", window.config = null;
3508 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; } }); }}
3509 function template(html,options){
3510 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}
3511 while(match=re.exec(html)){add(html.slice(cursor,match.index))(match[1],!0);cursor=match.index+match[0].length}
3512 add(html.substr(cursor,html.length-cursor));code+='return r.join("");';return new Function(code.replace(/[\r\t\n]/g,'')).apply(options)
3513 }
3514 function newfolder(e) {
3515 var t = document.getElementById("newfilename").value, n = document.querySelector('input[name="newfile"]:checked').value;
3516 null !== t && "" !== t && n && (window.location.hash = "#", window.location.search = "p=" + encodeURIComponent(e) + "&new=" + encodeURIComponent(t) + "&type=" + encodeURIComponent(n))
3517 }
3518 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))}
3519 function change_checkboxes(e, t) { for (var n = e.length - 1; n >= 0; n--) e[n].checked = "boolean" == typeof t ? t : !e[n].checked }
3520 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 }
3521 function select_all() { change_checkboxes(get_checkboxes(), !0) }
3522 function unselect_all() { change_checkboxes(get_checkboxes(), !1) }
3523 function invert_all() { change_checkboxes(get_checkboxes()) }
3524 function checkbox_toggle() { var e = get_checkboxes(); e.push(this), change_checkboxes(e) }
3525 function backup(e, t) { //Create file backup with .bck
3526 var n = new XMLHttpRequest,
3527 a = "path=" + e + "&file=" + t + "&type=backup&ajax=true";
3528 return n.open("POST", "", !0), n.setRequestHeader("Content-type", "application/x-www-form-urlencoded"), n.onreadystatechange = function () {
3529 4 == n.readyState && 200 == n.status && toast(n.responseText)
3530 }, n.send(a), !1
3531 }
3532 // Toast message
3533 function toast(txt) { var x = document.getElementById("snackbar");x.innerHTML=txt;x.className = "show";setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000); }
3534 //Save file
3535 function edit_save(e, t) {
3536 var n = "ace" == t ? editor.getSession().getValue() : document.getElementById("normal-editor").value;
3537 if (n) {
3538 if(true){
3539 var data = {ajax: true, content: n, type: 'save'};
3540
3541 $.ajax({
3542 type: "POST",
3543 url: window.location,
3544 // The key needs to match your method's input parameter (case-sensitive).
3545 data: JSON.stringify(data),
3546 contentType: "multipart/form-data-encoded; charset=utf-8",
3547 //dataType: "json",
3548 success: function(mes){toast("Saved Successfully"); window.onbeforeunload = function() {return}},
3549 failure: function(mes) {toast("Error: try again");}
3550 });
3551
3552 }
3553 else{
3554 var a = document.createElement("form");
3555 a.setAttribute("method", "POST"), a.setAttribute("action", "");
3556 var o = document.createElement("textarea");
3557 o.setAttribute("type", "textarea"), o.setAttribute("name", "savedata");
3558 var c = document.createTextNode(n);
3559 o.appendChild(c), a.appendChild(o), document.body.appendChild(a), a.submit()
3560 }
3561 }
3562 }
3563 //Check latest version
3564 function latest_release_info(v) {
3565 if(!!window.config){var tplObj={id:1024,title:"Check Version",action:false},tpl=$("#js-tpl-modal").html();
3566 if(window.config.version!=v){tplObj.content=window.config.newUpdate;}else{tplObj.content=window.config.noUpdate;}
3567 $('#wrapper').append(template(tpl,tplObj));$("#js-ModalCenter-1024").modal('show');}else{fm_get_config();}
3568 }
3569 function show_new_pwd() { $(".js-new-pwd").toggleClass('hidden'); }
3570 //Save Settings
3571 function save_settings($this) {
3572 let form = $($this);
3573 $.ajax({
3574 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3575 success: function (data) {if(data) { window.location.reload();}}
3576 }); return false;
3577 }
3578 //Create new password hash
3579 function new_password_hash($this) {
3580 let form = $($this), $pwd = $("#js-pwd-result"); $pwd.val('');
3581 $.ajax({
3582 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3583 success: function (data) { if(data) { $pwd.val(data); } }
3584 }); return false;
3585 }
3586 //Upload files using URL @param {Object}
3587 function upload_from_url($this) {
3588 let form = $($this), resultWrapper = $("div#js-url-upload__list");
3589 $.ajax({
3590 type: form.attr('method'), url: form.attr('action'), data: form.serialize()+"&ajax="+true,
3591 beforeSend: function() { form.find("input[name=uploadurl]").attr("disabled","disabled"); form.find("button").hide(); form.find(".lds-facebook").addClass('show-me'); },
3592 success: function (data) {
3593 if(data) {
3594 data = JSON.parse(data);
3595 if(data.done) {
3596 resultWrapper.append('<div class="alert alert-success row">Uploaded Successful: '+data.done.name+'</div>'); form.find("input[name=uploadurl]").val('');
3597 } else if(data['fail']) { resultWrapper.append('<div class="alert alert-danger row">Error: '+data.fail.message+'</div>'); }
3598 form.find("input[name=uploadurl]").removeAttr("disabled");form.find("button").show();form.find(".lds-facebook").removeClass('show-me');
3599 }
3600 },
3601 error: function(xhr) {
3602 form.find("input[name=uploadurl]").removeAttr("disabled");form.find("button").show();form.find(".lds-facebook").removeClass('show-me');console.error(xhr);
3603 }
3604 }); return false;
3605 }
3606 //Search template
3607 function search_template(data) {
3608 var response = "";
3609 $.each(data, function (key, val) {
3610 response += `<li><a href="?p=${val.path}&view=${val.name}">${val.path}/${val.name}</a></li>`;
3611 });
3612 return response;
3613 }
3614 //search
3615 function fm_search() {
3616 var searchTxt = $("input#advanced-search").val(), searchWrapper = $("ul#search-wrapper"), path = $("#js-search-modal").attr("href"), _html = "", $loader = $("div.lds-facebook");
3617 if(!!searchTxt && searchTxt.length > 2 && path) {
3618 var data = {ajax: true, content: searchTxt, path:path, type: 'search'};
3619 $.ajax({
3620 type: "POST",
3621 url: window.location,
3622 data: data,
3623 beforeSend: function() {
3624 searchWrapper.html('');
3625 $loader.addClass('show-me');
3626 },
3627 success: function(data){
3628 $loader.removeClass('show-me');
3629 data = JSON.parse(data);
3630 if(data && data.length) {
3631 _html = search_template(data);
3632 searchWrapper.html(_html);
3633 } else { searchWrapper.html('<p class="m-2">No result found!<p>'); }
3634 },
3635 error: function(xhr) { $loader.removeClass('show-me'); searchWrapper.html('<p class="m-2">ERROR: Try again later!</p>'); },
3636 failure: function(mes) { $loader.removeClass('show-me'); searchWrapper.html('<p class="m-2">ERROR: Try again later!</p>');}
3637 });
3638 } else { searchWrapper.html("OOPS: minimum 3 characters required!"); }
3639 }
3640
3641 //on mouse hover image preview
3642 !function(s){s.previewImage=function(e){var o=s(document),t=".previewImage",a=s.extend({xOffset:20,yOffset:-20,fadeIn:"fast",css:{padding:"5px",border:"1px solid #cccccc","background-color":"#fff"},eventSelector:"[data-preview-image]",dataKey:"previewImage",overlayId:"preview-image-plugin-overlay"},e);return o.off(t),o.on("mouseover"+t,a.eventSelector,function(e){s("p#"+a.overlayId).remove();var o=s("<p>").attr("id",a.overlayId).css("position","absolute").css("display","none").append(s('<img class="c-preview-img">').attr("src",s(this).data(a.dataKey)));a.css&&o.css(a.css),s("body").append(o),o.css("top",e.pageY+a.yOffset+"px").css("left",e.pageX+a.xOffset+"px").fadeIn(a.fadeIn)}),o.on("mouseout"+t,a.eventSelector,function(){s("#"+a.overlayId).remove()}),o.on("mousemove"+t,a.eventSelector,function(e){s("#"+a.overlayId).css("top",e.pageY+a.yOffset+"px").css("left",e.pageX+a.xOffset+"px")}),this},s.previewImage()}(jQuery);
3643
3644
3645 // Dom Ready Event
3646 $(document).ready( function () {
3647 //load config
3648 fm_get_config();
3649 //dataTable init
3650 var $table = $('#main-table'),
3651 tableLng = $table.find('th').length,
3652 _targets = (tableLng && tableLng == 7 ) ? [0, 4,5,6] : tableLng == 5 ? [0,4] : [3],
3653 mainTable = $('#main-table').DataTable({"paging": false, "info": false, "columnDefs": [{"targets": _targets, "orderable": false}]
3654 });
3655 //search
3656 $('#search-addon').on( 'keyup', function () {
3657 mainTable.search( this.value ).draw();
3658 });
3659 $("input#advanced-search").on('keyup', function (e) {
3660 if (e.keyCode === 13) { fm_search(); }
3661 });
3662 $('#search-addon3').on( 'click', function () { fm_search(); });
3663 //upload nav tabs
3664 $(".fm-upload-wrapper .card-header-tabs").on("click", 'a', function(e){
3665 e.preventDefault();let target=$(this).data('target');
3666 $(".fm-upload-wrapper .card-header-tabs a").removeClass('active');$(this).addClass('active');
3667 $(".fm-upload-wrapper .card-tabs-container").addClass('hidden');$(target).removeClass('hidden');
3668 });
3669 });
3670</script>
3671<?php if (isset($_GET['edit']) && isset($_GET['env']) && FM_EDIT_FILE):
3672 $ext = "javascript";
3673 $ext = pathinfo($_GET["edit"], PATHINFO_EXTENSION);
3674 ?>
3675 <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.1/ace.js"></script>
3676 <script>
3677 var editor = ace.edit("editor");
3678 editor.getSession().setMode( {path:"ace/mode/<?php echo $ext; ?>", inline:true} );
3679 //editor.setTheme("ace/theme/twilight"); //Dark Theme
3680 function ace_commend (cmd) { editor.commands.exec(cmd, editor); }
3681 editor.commands.addCommands([{
3682 name: 'save', bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
3683 exec: function(editor) { edit_save(this, 'ace'); }
3684 }]);
3685 function renderThemeMode() {
3686 var $modeEl = $("select#js-ace-mode"), $themeEl = $("select#js-ace-theme"), $fontSizeEl = $("select#js-ace-fontSize"), optionNode = function(type, arr){ var $Option = ""; $.each(arr, function(i, val) { $Option += "<option value='"+type+i+"'>" + val + "</option>"; }); return $Option; },
3687 _data = {"aceTheme":{"bright":{"chrome":"Chrome","clouds":"Clouds","crimson_editor":"Crimson Editor","dawn":"Dawn","dreamweaver":"Dreamweaver","eclipse":"Eclipse","github":"GitHub","iplastic":"IPlastic","solarized_light":"Solarized Light","textmate":"TextMate","tomorrow":"Tomorrow","xcode":"XCode","kuroir":"Kuroir","katzenmilch":"KatzenMilch","sqlserver":"SQL Server"},"dark":{"ambiance":"Ambiance","chaos":"Chaos","clouds_midnight":"Clouds Midnight","dracula":"Dracula","cobalt":"Cobalt","gruvbox":"Gruvbox","gob":"Green on Black","idle_fingers":"idle Fingers","kr_theme":"krTheme","merbivore":"Merbivore","merbivore_soft":"Merbivore Soft","mono_industrial":"Mono Industrial","monokai":"Monokai","pastel_on_dark":"Pastel on dark","solarized_dark":"Solarized Dark","terminal":"Terminal","tomorrow_night":"Tomorrow Night","tomorrow_night_blue":"Tomorrow Night Blue","tomorrow_night_bright":"Tomorrow Night Bright","tomorrow_night_eighties":"Tomorrow Night 80s","twilight":"Twilight","vibrant_ink":"Vibrant Ink"}},"aceMode":{"javascript":"JavaScript","abap":"ABAP","abc":"ABC","actionscript":"ActionScript","ada":"ADA","apache_conf":"Apache Conf","asciidoc":"AsciiDoc","asl":"ASL","assembly_x86":"Assembly x86","autohotkey":"AutoHotKey","apex":"Apex","batchfile":"BatchFile","bro":"Bro","c_cpp":"C and C++","c9search":"C9Search","cirru":"Cirru","clojure":"Clojure","cobol":"Cobol","coffee":"CoffeeScript","coldfusion":"ColdFusion","csharp":"C#","csound_document":"Csound Document","csound_orchestra":"Csound","csound_score":"Csound Score","css":"CSS","curly":"Curly","d":"D","dart":"Dart","diff":"Diff","dockerfile":"Dockerfile","dot":"Dot","drools":"Drools","edifact":"Edifact","eiffel":"Eiffel","ejs":"EJS","elixir":"Elixir","elm":"Elm","erlang":"Erlang","forth":"Forth","fortran":"Fortran","fsharp":"FSharp","fsl":"FSL","ftl":"FreeMarker","gcode":"Gcode","gherkin":"Gherkin","gitignore":"Gitignore","glsl":"Glsl","gobstones":"Gobstones","golang":"Go","graphqlschema":"GraphQLSchema","groovy":"Groovy","haml":"HAML","handlebars":"Handlebars","haskell":"Haskell","haskell_cabal":"Haskell Cabal","haxe":"haXe","hjson":"Hjson","html":"HTML","html_elixir":"HTML (Elixir)","html_ruby":"HTML (Ruby)","ini":"INI","io":"Io","jack":"Jack","jade":"Jade","java":"Java","json":"JSON","jsoniq":"JSONiq","jsp":"JSP","jssm":"JSSM","jsx":"JSX","julia":"Julia","kotlin":"Kotlin","latex":"LaTeX","less":"LESS","liquid":"Liquid","lisp":"Lisp","livescript":"LiveScript","logiql":"LogiQL","lsl":"LSL","lua":"Lua","luapage":"LuaPage","lucene":"Lucene","makefile":"Makefile","markdown":"Markdown","mask":"Mask","matlab":"MATLAB","maze":"Maze","mel":"MEL","mixal":"MIXAL","mushcode":"MUSHCode","mysql":"MySQL","nix":"Nix","nsis":"NSIS","objectivec":"Objective-C","ocaml":"OCaml","pascal":"Pascal","perl":"Perl","perl6":"Perl 6","pgsql":"pgSQL","php_laravel_blade":"PHP (Blade Template)","php":"PHP","puppet":"Puppet","pig":"Pig","powershell":"Powershell","praat":"Praat","prolog":"Prolog","properties":"Properties","protobuf":"Protobuf","python":"Python","r":"R","razor":"Razor","rdoc":"RDoc","red":"Red","rhtml":"RHTML","rst":"RST","ruby":"Ruby","rust":"Rust","sass":"SASS","scad":"SCAD","scala":"Scala","scheme":"Scheme","scss":"SCSS","sh":"SH","sjs":"SJS","slim":"Slim","smarty":"Smarty","snippets":"snippets","soy_template":"Soy Template","space":"Space","sql":"SQL","sqlserver":"SQLServer","stylus":"Stylus","svg":"SVG","swift":"Swift","tcl":"Tcl","terraform":"Terraform","tex":"Tex","text":"Text","textile":"Textile","toml":"Toml","tsx":"TSX","twig":"Twig","typescript":"Typescript","vala":"Vala","vbscript":"VBScript","velocity":"Velocity","verilog":"Verilog","vhdl":"VHDL","visualforce":"Visualforce","wollok":"Wollok","xml":"XML","xquery":"XQuery","yaml":"YAML","django":"Django"},"fontSize":{8:8,10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,20:20,22:22,24:24,26:26,30:30}};
3688 if(_data && _data.aceMode) { $modeEl.html(optionNode("ace/mode/", _data.aceMode)); }
3689 if(_data && _data.aceTheme) { var lightTheme = optionNode("ace/theme/", _data.aceTheme.bright), darkTheme = optionNode("ace/theme/", _data.aceTheme.dark); $themeEl.html("<optgroup label=\"Bright\">"+lightTheme+"</optgroup><optgroup label=\"Dark\">"+darkTheme+"</optgroup>");}
3690 if(_data && _data.fontSize) { $fontSizeEl.html(optionNode("", _data.fontSize)); }
3691 $fontSizeEl.val(12).change(); //set default font size in drop down
3692 }
3693
3694 $(function(){
3695 renderThemeMode();
3696 $(".js-ace-toolbar").on("click", 'button', function(e){
3697 e.preventDefault();
3698 let cmdValue = $(this).attr("data-cmd"), editorOption = $(this).attr("data-option");
3699 if(cmdValue && cmdValue != "none") {
3700 ace_commend(cmdValue);
3701 } else if(editorOption) {
3702 if(editorOption == "fullscreen") {
3703 (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)
3704 &&(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());
3705 } else if(editorOption == "wrap") {
3706 let wrapStatus = (editor.getSession().getUseWrapMode()) ? false : true;
3707 editor.getSession().setUseWrapMode(wrapStatus);
3708 } else if(editorOption == "help") {
3709 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');
3710 }
3711 }
3712 });
3713 $("select#js-ace-mode, select#js-ace-theme, select#js-ace-fontSize").on("change", function(e){
3714 e.preventDefault();
3715 let selectedValue = $(this).val(), selectionType = $(this).attr("data-type");
3716 if(selectedValue && selectionType == "mode") {
3717 editor.getSession().setMode(selectedValue);
3718 } else if(selectedValue && selectionType == "theme") {
3719 editor.setTheme(selectedValue);
3720 }else if(selectedValue && selectionType == "fontSize") {
3721 editor.setFontSize(parseInt(selectedValue));
3722 }
3723 });
3724 });
3725 </script>
3726<?php endif; ?>
3727<div id="snackbar"></div>
3728</body>
3729</html>
3730<?php
3731}
3732
3733/**
3734 * Show image
3735 * @param string $img
3736 */
3737function fm_show_image($img)
3738{
3739 $modified_time = gmdate('D, d M Y 00:00:00') . ' GMT';
3740 $expires_time = gmdate('D, d M Y 00:00:00', strtotime('+1 day')) . ' GMT';
3741
3742 $img = trim($img);
3743 $images = fm_get_images();
3744 $image = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==';
3745 if (isset($images[$img])) {
3746 $image = $images[$img];
3747 }
3748 $image = base64_decode($image);
3749 if (function_exists('mb_strlen')) {
3750 $size = mb_strlen($image, '8bit');
3751 } else {
3752 $size = strlen($image);
3753 }
3754
3755 if (function_exists('header_remove')) {
3756 header_remove('Cache-Control');
3757 header_remove('Pragma');
3758 } else {
3759 header('Cache-Control:');
3760 header('Pragma:');
3761 }
3762
3763 header('Last-Modified: ' . $modified_time, true, 200);
3764 header('Expires: ' . $expires_time);
3765 header('Content-Length: ' . $size);
3766 header('Content-Type: image/png');
3767 echo $image;
3768
3769 exit;
3770}
3771
3772
3773/**
3774 * Language Translation System
3775 * @param string $txt
3776 * @return string
3777 */
3778function lng($txt) {
3779 global $lang;
3780
3781 // English Language
3782 $tr['en']['AppName'] = 'Tiny File Manager'; $tr['en']['AppTitle'] = 'File Manager';
3783 $tr['en']['Login'] = 'Sign in'; $tr['en']['Username'] = 'Username';
3784 $tr['en']['Password'] = 'Password'; $tr['en']['Logout'] = 'Sign Out';
3785 $tr['en']['Move'] = 'Move'; $tr['en']['Copy'] = 'Copy';
3786 $tr['en']['Save'] = 'Save'; $tr['en']['SelectAll'] = 'Select all';
3787 $tr['en']['UnSelectAll'] = 'Unselect all'; $tr['en']['File'] = 'File';
3788 $tr['en']['Back'] = 'Back'; $tr['en']['Size'] = 'Size';
3789 $tr['en']['Perms'] = 'Perms'; $tr['en']['Modified'] = 'Modified';
3790 $tr['en']['Owner'] = 'Owner'; $tr['en']['Search'] = 'Search';
3791 $tr['en']['NewItem'] = 'New Item'; $tr['en']['Folder'] = 'Folder';
3792 $tr['en']['Delete'] = 'Delete'; $tr['en']['Rename'] = 'Rename';
3793 $tr['en']['CopyTo'] = 'Copy to'; $tr['en']['DirectLink'] = 'Direct link';
3794 $tr['en']['UploadingFiles'] = 'Upload Files'; $tr['en']['ChangePermissions'] = 'Change Permissions';
3795 $tr['en']['Copying'] = 'Copying'; $tr['en']['CreateNewItem'] = 'Create New Item';
3796 $tr['en']['Name'] = 'Name'; $tr['en']['AdvancedEditor'] = 'Advanced Editor';
3797 $tr['en']['RememberMe'] = 'Remember Me'; $tr['en']['Actions'] = 'Actions';
3798 $tr['en']['Upload'] = 'Upload'; $tr['en']['Cancel'] = 'Cancel';
3799 $tr['en']['InvertSelection']= 'Invert Selection'; $tr['en']['DestinationFolder'] = 'Destination Folder';
3800 $tr['en']['ItemType'] = 'Item Type'; $tr['en']['ItemName'] = 'Item Name';
3801 $tr['en']['CreateNow'] = 'Create Now'; $tr['en']['Download'] = 'Download';
3802 $tr['en']['Open'] = 'Open'; $tr['en']['UnZip'] = 'UnZip';
3803 $tr['en']['UnZipToFolder'] = 'UnZip to folder'; $tr['en']['Edit'] = 'Edit';
3804 $tr['en']['NormalEditor'] = 'Normal Editor'; $tr['en']['BackUp'] = 'Back Up';
3805 $tr['en']['SourceFolder'] = 'Source Folder'; $tr['en']['Files'] = 'Files';
3806 $tr['en']['Move'] = 'Move'; $tr['en']['Change'] = 'Change';
3807 $tr['en']['Settings'] = 'Settings'; $tr['en']['Language'] = 'Language';
3808 $tr['en']['MemoryUsed'] = 'Memory used'; $tr['en']['PartitionSize'] = 'Partition size';
3809 $tr['en']['ErrorReporting'] = 'Error Reporting'; $tr['en']['ShowHiddenFiles'] = 'Show Hidden Files';
3810 $tr['en']['Full size'] = 'Full size'; $tr['en']['Help'] = 'Help';
3811 $tr['en']['Free of'] = 'Free of'; $tr['en']['Preview'] = 'Preview';
3812 $tr['en']['Help Documents'] = 'Help Documents'; $tr['en']['Report Issue'] = 'Report Issue';
3813 $tr['en']['Generate'] = 'Generate'; $tr['en']['FullSize'] = 'Full Size';
3814 $tr['en']['FreeOf'] = 'free of'; $tr['en']['CalculateFolderSize']= 'Calculate folder size';
3815 $tr['en']['ProcessID'] = 'Process ID';
3816 $tr['en']['HideColumns'] = 'Hide Perms/Owner columns';
3817 $tr['en']['Check Latest Version']= 'Check Latest Version'; $tr['en']['Generate new password hash'] = 'Generate new password hash';
3818
3819 $i18n = fm_get_translations($tr);
3820 $tr = $i18n ? $i18n : $tr;
3821
3822 if (!strlen($lang)) $lang = 'en';
3823 if (isset($tr[$lang][$txt])) return fm_enc($tr[$lang][$txt]);
3824 else if (isset($tr['en'][$txt])) return fm_enc($tr['en'][$txt]);
3825 else return "$txt";
3826}
3827
3828/**
3829 * Get base64-encoded images
3830 * @return array
3831 */
3832function fm_get_images()
3833{
3834 return array(
3835 'favicon' => 'Qk04AgAAAAAAADYAAAAoAAAAEAAAABAAAAABABAAAAAAAAICAAASCwAAEgsAAAAAAAAAAAAAIQQhBCEEIQQhBCEEIQQhBCEEIQ
3836 QhBCEEIQQhBCEEIQQhBCEEIQQhBHNO3n/ef95/vXetNSEEIQQhBCEEIQQhBCEEIQQhBCEEc07ef95/3n/ef95/1lohBCEEIQQhBCEEIQQhBCEEIQ
3837 RzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBHNO3n/efyEEMUbef95/IQQhBCEEIQQhBCEEIQQhBCEErTVzTnNOIQQxRt5/3n8hBCEEIQ
3838 QhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBCEEIQQxRt5/3n+cc2stIQQhBCEEIQQhBCEEIQQhBCEEIQQIIZxz3n
3839 /ef5xzay0hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBK01c05zTiEEMUbef95/IQQhBCEEIQQhBCEEIQ
3840 QhBCEEc07ef95/IQQxRt5/3n8hBCEEIQQhBCEEIQQhBCEEIQRzTt5/3n8hBDFG3n/efyEEIQQhBCEEIQQhBCEEIQQhBKUUOWfef95/3n/ef95/IQ
3841 QhBCEEIQQhBCEEIQQhBCEEIQQhBJRW3n/ef95/3n8hBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQhBCEEIQQAAA=='
3842 );
3843}
3844
3845?>