<?php

namespace onespace\tools\widgets\tinyfilebrowser\traits;

use onespace\tools\widgets\tinyfilebrowser\lib\FMZipper;
use onespace\tools\widgets\tinyfilebrowser\lib\FMZipperTar;
use Exception;
use PharData;
use stdClass;

trait FMActions {

    protected function fm_ajax(): never {
        if (!$this->verifyToken($_POST['token'])) {
            header('HTTP/1.0 401 Unauthorized');
            die("Invalid Token.");
        }

        //search : get list of files from the current folder
        if (isset($_POST['type']) && $_POST['type'] == "search") {
            $dir = $_POST['path'] == "." ? '' : $_POST['path'];
            $response = $this->scan($this->fm_clean_path($dir), $_POST['content']);
            echo json_encode($response);
            exit();
        }

        // save editor file
        if (isset($_POST['type']) && $_POST['type'] == "save") {
            // get current path
            $path = FM_ROOT_PATH;
            if (FM_PATH != '') {
                $path .= '/' . FM_PATH;
            }
            // check path
            if (!is_dir($path)) {
                $this->fm_redirect(FM_SELF_URL . '?p=');
            }
            $file = $_GET['edit'];
            $file = $this->fm_clean_path($file);
            $file = str_replace('/', '', $file);
            if ($file == '' || !is_file($path . '/' . $file)) {
                $this->fm_set_msg($this->lng('File not found'), 'error');
                $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
            }
            header('X-XSS-Protection:0');
            $file_path = $path . '/' . $file;

            $writedata = $_POST['content'];
            $fd = fopen($file_path, "w");
            $write_results = @fwrite($fd, $writedata);
            fclose($fd);
            if ($write_results === false) {
                header("HTTP/1.1 500 Internal Server Error");
                die("Could Not Write File! - Check Permissions / Ownership");
            }
            die(true);
        }

        // backup files
        if (isset($_POST['type']) && $_POST['type'] == "backup" && !empty($_POST['file'])) {
            $fileName = $this->fm_clean_path($_POST['file']);
            $fullPath = FM_ROOT_PATH . '/';
            if (!empty($_POST['path'])) {
                $relativeDirPath = $this->fm_clean_path($_POST['path']);
                $fullPath .= "{$relativeDirPath}/";
            }
            $date = date("dMy-His");
            $newFileName = "{$fileName}-{$date}.bak";
            $fullyQualifiedFileName = $fullPath . $fileName;
            try {
                if (!file_exists($fullyQualifiedFileName)) {
                    throw new Exception("File {$fileName} not found");
                }
                if (copy($fullyQualifiedFileName, $fullPath . $newFileName)) {
                    echo "Backup {$newFileName} created";
                } else {
                    throw new Exception("Could not copy file {$fileName}");
                }
            } catch (Exception $e) {
                echo $e->getMessage();
            }
        }

        exit();
    }
    
    
    protected function fm_delete() {
        $del = str_replace('/', '', $this->fm_clean_path($_GET['del']));
        if ($del != '' && $del != '..' && $del != '.' && $this->verifyToken($_POST['token'])) {
            $path = FM_ROOT_PATH;
            if (FM_PATH != '') {
                $path .= '/' . FM_PATH;
            }
            $is_dir = is_dir($path . '/' . $del);
            if ($this->fm_rdelete($path . '/' . $del)) {
                $msg = $is_dir ? $this->lng('Folder') . ' <b>%s</b> ' . $this->lng('Deleted') : $this->lng('File') . ' <b>%s</b> ' . $this->lng('Deleted');
                $this->fm_set_msg(sprintf($msg, $this->fm_enc($del)));
            } else {
                $msg = $is_dir ? $this->lng('Folder') . ' <b>%s</b> ' . $this->lng('not deleted') : $this->lng('File') . ' <b>%s</b> ' . $this->lng('not deleted');
                $this->fm_set_msg(sprintf($msg, $this->fm_enc($del)), 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('Invalid file or folder name'), 'error');
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_create() {
        $type = urldecode($_POST['newfile']);
        $new = str_replace('/', '', $this->fm_clean_path(strip_tags($_POST['newfilename'])));
        if ($this->fm_isvalid_filename($new) && $new != '' && $new != '..' && $new != '.' && $this->verifyToken($_POST['token'])) {
            $path = FM_ROOT_PATH;
            if (FM_PATH != '') {
                $path .= '/' . FM_PATH;
            }
            if ($type == "file") {
                if (!file_exists($path . '/' . $new)) {
                    if ($this->fm_is_valid_ext($new)) {
                        @fopen($path . '/' . $new, 'w') or die('Cannot open file:  ' . $new);
                        $this->fm_set_msg(sprintf($this->lng('File') . ' <b>%s</b> ' . $this->lng('Created'), $this->fm_enc($new)));
                    } else {
                        $this->fm_set_msg($this->lng('File extension is not allowed'), 'error');
                    }
                } else {
                    $this->fm_set_msg(sprintf($this->lng('File') . ' <b>%s</b> ' . $this->lng('already exists'), $this->fm_enc($new)), 'alert');
                }
            } else {
                if ($this->fm_mkdir($path . '/' . $new, false) === true) {
                    $this->fm_set_msg(sprintf($this->lng('Folder') . ' <b>%s</b> ' . $this->lng('Created'), $new));
                } elseif ($this->fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) {
                    $this->fm_set_msg(sprintf($this->lng('Folder') . ' <b>%s</b> ' . $this->lng('already exists'), $this->fm_enc($new)), 'alert');
                } else {
                    $this->fm_set_msg(sprintf($this->lng('Folder') . ' <b>%s</b> ' . $this->lng('not created'), $this->fm_enc($new)), 'error');
                }
            }
        } else {
            $this->fm_set_msg($this->lng('Invalid characters in file or folder name'), 'error');
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_copy_files() {
        // from
        $copy = urldecode($_GET['copy']);
        $copy = $this->fm_clean_path($copy);
        // empty path
        if ($copy == '') {
            $this->fm_set_msg($this->lng('Source path not defined'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }
        // abs path from
        $from = FM_ROOT_PATH . '/' . $copy;
        // abs path to
        $dest = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $dest .= '/' . FM_PATH;
        }
        $dest .= '/' . basename($from);
        // move?
        $move = isset($_GET['move']);
        $move = $this->fm_clean_path(urldecode($move));
        // copy/move/duplicate
        if ($from != $dest) {
            $msg_from = trim(FM_PATH . '/' . basename($from), '/');
            if ($move) { // Move and to != from so just perform move
                $rename = $this->fm_rename($from, $dest);
                if ($rename) {
                    $this->fm_set_msg(sprintf($this->lng('Moved from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($msg_from)));
                } elseif ($rename === null) {
                    $this->fm_set_msg($this->lng('File or folder with this path already exists'), 'alert');
                } else {
                    $this->fm_set_msg(sprintf($this->lng('Error while moving from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($msg_from)), 'error');
                }
            } else { // Not move and to != from so copy with original name
                if ($this->fm_rcopy($from, $dest)) {
                    $this->fm_set_msg(sprintf($this->lng('Copied from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($msg_from)));
                } else {
                    $this->fm_set_msg(sprintf($this->lng('Error while copying from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($msg_from)), 'error');
                }
            }
        } else {
            if (!$move) { //Not move and to = from so duplicate
                $msg_from = trim(FM_PATH . '/' . basename($from), '/');
                $fn_parts = pathinfo($from);
                $extension_suffix = '';
                if (!is_dir($from)) {
                    $extension_suffix = '.' . $fn_parts['extension'];
                }
                //Create new name for duplicate
                $fn_duplicate = $fn_parts['dirname'] . '/' . $fn_parts['filename'] . '-' . date('YmdHis') . $extension_suffix;
                $loop_count = 0;
                $max_loop = 1000;
                // Check if a file with the duplicate name already exists, if so, make new name (edge case...)
                while (file_exists($fn_duplicate) & $loop_count < $max_loop) {
                    $fn_parts = pathinfo($fn_duplicate);
                    $fn_duplicate = $fn_parts['dirname'] . '/' . $fn_parts['filename'] . '-copy' . $extension_suffix;
                    $loop_count++;
                }
                if ($this->fm_rcopy($from, $fn_duplicate, False)) {
                    $this->fm_set_msg(sprintf('Copied from <b>%s</b> to <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($fn_duplicate)));
                } else {
                    $this->fm_set_msg(sprintf('Error while copying from <b>%s</b> to <b>%s</b>', $this->fm_enc($copy), $this->fm_enc($fn_duplicate)), 'error');
                }
            } else {
                $this->fm_set_msg($this->lng('Paths must be not equal'), 'alert');
            }
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_mass_copy() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg($this->lng('Invalid Token.'), 'error');
        }

        // from
        $path = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }
        // to
        $copy_to_path = FM_ROOT_PATH;
        $copy_to = $this->fm_clean_path($_POST['copy_to']);
        if ($copy_to != '') {
            $copy_to_path .= '/' . $copy_to;
        }
        if ($path == $copy_to_path) {
            $this->fm_set_msg($this->lng('Paths must be not equal'), 'alert');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }
        if (!is_dir($copy_to_path)) {
            if (!$this->fm_mkdir($copy_to_path, true)) {
                $this->fm_set_msg('Unable to create destination folder', 'error');
                $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
            }
        }
        // move?
        $move = isset($_POST['move']);
        // copy/move
        $errors = 0;
        $files = $_POST['file'];
        if (is_array($files) && count($files)) {
            foreach ($files as $f) {
                if ($f != '') {
                    $f = $this->fm_clean_path($f);
                    // abs path from
                    $from = $path . '/' . $f;
                    // abs path to
                    $dest = $copy_to_path . '/' . $f;
                    // do
                    if ($move) {
                        $rename = $this->fm_rename($from, $dest);
                        if ($rename === false) {
                            $errors++;
                        }
                    } else {
                        if (!$this->fm_rcopy($from, $dest)) {
                            $errors++;
                        }
                    }
                }
            }
            if ($errors == 0) {
                $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied';
                $this->fm_set_msg($msg);
            } else {
                $msg = $move ? 'Error while moving items' : 'Error while copying items';
                $this->fm_set_msg($msg, 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('Nothing selected'), 'alert');
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_rename_files() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg("Invalid Token.", 'error');
        }
        // old name
        $old = urldecode($_POST['rename_from']);
        $old = $this->fm_clean_path($old);
        $old = str_replace('/', '', $old);
        // new name
        $new = urldecode($_POST['rename_to']);
        $new = $this->fm_clean_path(strip_tags($new));
        $new = str_replace('/', '', $new);
        // path
        $path = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }
        // rename
        if ($this->fm_isvalid_filename($new) && $old != '' && $new != '') {
            if ($this->fm_rename($path . '/' . $old, $path . '/' . $new)) {
                $this->fm_set_msg(sprintf($this->lng('Renamed from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($old), $this->fm_enc($new)));
            } else {
                $this->fm_set_msg(sprintf($this->lng('Error while renaming from') . ' <b>%s</b> ' . $this->lng('to') . ' <b>%s</b>', $this->fm_enc($old), $this->fm_enc($new)), 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('Invalid characters in file name'), 'error');
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    // protected function fm_download() {
    //     if (!$this->verifyToken($_POST['token'])) {
    //         $this->fm_set_msg("Invalid Token.", 'error');
    //     }

    //     $dl = urldecode($_GET['dl']);
    //     $dl = $this->fm_clean_path($dl);
    //     $dl = str_replace('/', '', $dl);
    //     $path = FM_ROOT_PATH;
    //     if (FM_PATH != '') {
    //         $path .= '/' . FM_PATH;
    //     }
    //     if ($dl != '' && is_file($path . '/' . $dl)) {
    //         $this->fm_download_file($path . '/' . $dl, $dl, 1024);
    //         exit;
    //     } else {
    //         $this->fm_set_msg($this->lng('File not found'), 'error');
    //         $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    //     }
    // }
    
    
    protected function fm_upload() {
        // return json_encode(['success' => 'ok', 'code' => 200]);
        if (isset($_POST['token'])) {
            if (!$this->verifyToken($_POST['token'])) {
                $response = array('status' => 'error', 'info' => "Invalid Token.");
                echo json_encode($response);
                exit();
            }
        } else {
            $response = array('status' => 'error', 'info' => "Token Missing.");
            echo json_encode($response);
            exit();
        }

        $chunkIndex = $_POST['dzchunkindex'];
        $chunkTotal = $_POST['dztotalchunkcount'];
        $fullPathInput = $this->fm_clean_path($_REQUEST['fullpath']);

        $f = $_FILES;
        $path = FM_ROOT_PATH;
        $ds = DIRECTORY_SEPARATOR;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }

        $errors = 0;
        $uploads = 0;
        $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false;
        $response = array(
            'status' => 'error',
            'info'   => 'Oops! Try again'
        );

        $filename = $f['file']['name'];
        $tmp_name = $f['file']['tmp_name'];
        $ext = pathinfo($filename, PATHINFO_FILENAME) != '' ? strtolower(pathinfo($filename, PATHINFO_EXTENSION)) : '';
        $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true;

        if (!$this->fm_isvalid_filename($filename) && !$this->fm_isvalid_filename($fullPathInput)) {
            $response = array(
                'status'    => 'error',
                'info'      => "Invalid File name!",
            );
            echo json_encode($response);
            exit();
        }

        $targetPath = $path . $ds;
        if (is_writable($targetPath)) {
            $fullPath = $path . '/' . basename($fullPathInput);
            $folder = substr($fullPath, 0, strrpos($fullPath, "/"));

            if (!is_dir($folder)) {
                $old = umask(0);
                mkdir($folder, 0777, true);
                umask($old);
            }

            if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) {
                if ($chunkTotal) {
                    $out = @fopen("{$fullPath}.part", $chunkIndex == 0 ? "wb" : "ab");
                    if ($out) {
                        $in = @fopen($tmp_name, "rb");
                        if ($in) {
                            if (PHP_VERSION_ID < 80009) {
                                // workaround https://bugs.php.net/bug.php?id=81145
                                do {
                                    for (;;) {
                                        $buff = fread($in, 4096);
                                        if ($buff === false || $buff === '') {
                                            break;
                                        }
                                        fwrite($out, $buff);
                                    }
                                } while (!feof($in));
                            } else {
                                stream_copy_to_stream($in, $out);
                            }
                            $response = array(
                                'status'    => 'success',
                                'info' => "file upload successful"
                            );
                        } else {
                            $response = array(
                                'status'    => 'error',
                                'info' => "failed to open output stream",
                                'errorDetails' => error_get_last()
                            );
                        }
                        @fclose($in);
                        @fclose($out);
                        @unlink($tmp_name);

                        $response = array(
                            'status'    => 'success',
                            'info' => "file upload successful"
                        );
                    } else {
                        $response = array(
                            'status'    => 'error',
                            'info' => "failed to open output stream"
                        );
                    }

                    if ($chunkIndex == $chunkTotal - 1) {
                        if (file_exists($fullPath)) {
                            $ext_1 = $ext ? '.' . $ext : '';
                            $fullPathTarget = $path . '/' . basename($fullPathInput, $ext_1) . '_' . date('ymdHis') . $ext_1;
                        } else {
                            $fullPathTarget = $fullPath;
                        }
                        rename("{$fullPath}.part", $fullPathTarget);
                    }
                } else if (move_uploaded_file($tmp_name, $fullPath)) {
                    // Be sure that the file has been uploaded
                    if (file_exists($fullPath)) {
                        $response = array(
                            'status'    => 'success',
                            'info' => "file upload successful"
                        );
                    } else {
                        $response = array(
                            'status' => 'error',
                            'info'   => 'Couldn\'t upload the requested file.'
                        );
                    }
                } else {
                    $response = array(
                        'status'    => 'error',
                        'info'      => "Error while uploading files. Uploaded files $uploads",
                    );
                }
            }
        } else {
            $response = array(
                'status' => 'error',
                'info'   => 'The specified folder for upload isn\'t writeable.'
            );
        }
        // Return the response
        echo json_encode($response);
        exit();
    }
    
    
    protected function fm_mass_delete() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg($this->lng("Invalid Token."), 'error');
        }

        $path = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }

        $errors = 0;
        $files = $_POST['file'];
        if (is_array($files) && count($files)) {
            foreach ($files as $f) {
                if ($f != '') {
                    $new_path = $path . '/' . $f;
                    if (!$this->fm_rdelete($new_path)) {
                        $errors++;
                    }
                }
            }
            if ($errors == 0) {
                $this->fm_set_msg($this->lng('Selected files and folder deleted'));
            } else {
                $this->fm_set_msg($this->lng('Error while deleting items'), 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('Nothing selected'), 'alert');
        }

        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_zip_files() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg($this->lng("Invalid Token."), 'error');
        }

        $path = FM_ROOT_PATH;
        $ext = 'zip';
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }

        //set pack type
        $ext = isset($_POST['tar']) ? 'tar' : 'zip';

        if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
            $this->fm_set_msg($this->lng('Operations with archives are not available'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }

        $files = $_POST['file'];
        $sanitized_files = [];

        // clean path
        foreach ($files as $file) {
            array_push($sanitized_files, $this->fm_clean_path($file));
        }

        $files = $sanitized_files;

        if (!empty($files)) {
            chdir($path);

            if (count($files) == 1) {
                $one_file = reset($files);
                $one_file = basename($one_file);
                $zipname = $one_file . '_' . date('ymd_His') . '.' . $ext;
            } else {
                $zipname = 'archive_' . date('ymd_His') . '.' . $ext;
            }

            if ($ext == 'zip') {
                $zipper = new FMZipper();
                $res = $zipper->create($zipname, $files);
            } elseif ($ext == 'tar') {
                $tar = new FMZipperTar();
                $res = $tar->create($zipname, $files);
            }

            if ($res) {
                $this->fm_set_msg(sprintf($this->lng('Archive') . ' <b>%s</b> ' . $this->lng('Created'), $this->fm_enc($zipname)));
            } else {
                $this->fm_set_msg($this->lng('Archive not created'), 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('Nothing selected'), 'alert');
        }

        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_unzip_files() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg($this->lng("Invalid Token."), 'error');
        }

        $unzip = urldecode($_POST['unzip']);
        $unzip = $this->fm_clean_path($unzip);
        $unzip = str_replace('/', '', $unzip);
        $isValid = false;

        $path = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }

        if ($unzip != '' && is_file($path . '/' . $unzip)) {
            $zip_path = $path . '/' . $unzip;
            $ext = pathinfo($zip_path, PATHINFO_EXTENSION);
            $isValid = true;
        } else {
            $this->fm_set_msg($this->lng('File not found'), 'error');
        }

        if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) {
            $this->fm_set_msg($this->lng('Operations with archives are not available'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }

        if ($isValid) {
            //to folder
            $tofolder = '';
            if (isset($_POST['tofolder'])) {
                $tofolder = pathinfo($zip_path, PATHINFO_FILENAME);
                if ($this->fm_mkdir($path . '/' . $tofolder, true)) {
                    $path .= '/' . $tofolder;
                }
            }

            if ($ext == "zip") {
                $zipper = new FMZipper();
                $res = $zipper->unzip($zip_path, $path);
            } elseif ($ext == "tar") {
                try {
                    $gzipper = new PharData($zip_path);
                    if (@$gzipper->extractTo($path, null, true)) {
                        $res = true;
                    } else {
                        $res = false;
                    }
                } catch (Exception $e) {
                    //TODO:: need to handle the error
                    $res = true;
                }
            }

            if ($res) {
                $this->fm_set_msg($this->lng('Archive unpacked'));
            } else {
                $this->fm_set_msg($this->lng('Archive not unpacked'), 'error');
            }
        } else {
            $this->fm_set_msg($this->lng('File not found'), 'error');
        }
        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
    
    
    protected function fm_change_perms() {
        if (!$this->verifyToken($_POST['token'])) {
            $this->fm_set_msg($this->lng("Invalid Token."), 'error');
        }

        $path = FM_ROOT_PATH;
        if (FM_PATH != '') {
            $path .= '/' . FM_PATH;
        }

        $file = $_POST['chmod'];
        $file = $this->fm_clean_path($file);
        $file = str_replace('/', '', $file);
        if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) {
            $this->fm_set_msg($this->lng('File not found'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }

        $mode = 0;
        if (!empty($_POST['ur'])) {
            $mode |= 0400;
        }
        if (!empty($_POST['uw'])) {
            $mode |= 0200;
        }
        if (!empty($_POST['ux'])) {
            $mode |= 0100;
        }
        if (!empty($_POST['gr'])) {
            $mode |= 0040;
        }
        if (!empty($_POST['gw'])) {
            $mode |= 0020;
        }
        if (!empty($_POST['gx'])) {
            $mode |= 0010;
        }
        if (!empty($_POST['or'])) {
            $mode |= 0004;
        }
        if (!empty($_POST['ow'])) {
            $mode |= 0002;
        }
        if (!empty($_POST['ox'])) {
            $mode |= 0001;
        }

        if (@chmod($path . '/' . $file, $mode)) {
            $this->fm_set_msg($this->lng('Permissions changed'));
        } else {
            $this->fm_set_msg($this->lng('Permissions not changed'), 'error');
        }

        $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
    }
}
