<?php

namespace onespace\tools\widgets\tinyfilebrowser\traits;

use Yii;


/**
 * Contains the various forms used by TinyFileBrowser Widget.
 */

trait FMForms {

    private function init_html(): string {
        return "<div id='fm_data_loaded'></div>";
    }


    protected function main_form($files, $folders, $path, $parent): string {
        DEFINE('ROOT_DIR', $parent === false);
        $html = $this->init_html();

        $set_id = isset($_GET['id']) && !empty($_GET['id']) ? "&id={$_GET['id']}" : '';

        $html .= $this->fm_show_header(); // HEADER
        $html .= $this->fm_show_nav_path(FM_PATH); // current path

        // show alert messages
        $html .= $this->fm_show_message();

        $num_files = count($files);
        $num_folders = count($folders);
        $all_files_size = 0;
        $tableTheme = (FM_THEME == "dark") ? "text-white bg-dark table-dark" : "bg-white";

        $html .= '<form action="" method="post" class="pt-3">';
        $html .= "<input type='hidden' name='p' value='{$this->fm_enc(FM_PATH)}'>";
        $html .= '<input type="hidden" name="group" value="1">';
        $html .= "<input type='hidden' name='token' value='{$_SESSION['token']}'>";
        $html .= '<div class="table-responsive">';
        $html .= "<table class='table table-bordered table-hover table-sm {$tableTheme}' id='main-table'>";
        $html .= '<thead class="thead-white">';
        $html .= '<tr>';
        if (!FM_READONLY) {
            $html .= '<th style="width:3%" class="custom-checkbox-header">';
            $html .= '<div class="custom-control custom-checkbox">';
            $html .= '<input type="checkbox" class="custom-control-input" id="js-select-all-items">';
            $html .= '<label class="custom-control-label" for="js-select-all-items"></label>';
            $html .= '</div>';
            $html .= '</th>';
        }
        $html .= "<th>Name</th>";
        // if (!FM_READONLY && ROOT_DIR) {
        //     $html .= "<th>Details</th>";
        // }
        $html .= "<th>Size</th>";
        $html .= "<th>Modified</th>";
        if (!FM_READONLY && !ROOT_DIR) {
            $html .= '<th>Actions</th>';
        }
        $html .= '</tr>';
        $html .= '</thead>';
        // link to parent folder
        if (!ROOT_DIR) {
            $html .= '<tr>';
            if (!FM_READONLY) {
                $html .= '<td class="nosort"></td>';
            }
            $html .= "<td class='border-0' data-sort>";
            $html .= "<a href='?p=" . urlencode($parent) . "{$set_id}'>";
            $html .= '<i class="fa fa-chevron-circle-left go-back"></i> ..</a></td>';
            $html .= '<td class="border-0" data-order></td>';
            $html .= '<td class="border-0" data-order></td>';
            if (!FM_READONLY) {
                $html .= '<td class="border-0"></td>';
            }
            $html .= '</tr>';
        }

        /**
         * FOLDERS
         */
        $ii = 3399;
        $i = 0;
        foreach ($folders as $fname => $f) {
            $filesize_raw = "";
            $filesize = $this->lng('Folder');
            if (isset($this->file_path)) {
                // Standard File Path
                $is_link = is_link($path . '/' . $f);
                $img = $is_link ? 'icon-link_folder' : 'fa fa-folder-o';
                $modif_raw = filemtime($path . '/' . $f);
            } else {
                // File over FTP
                $is_link = is_link($f->path());
                $img = $is_link ? 'icon-link_folder' : 'fa fa-folder-o';
                $modif_raw = $f->lastModified();
                // $perms = substr(decoct(fileperms($f->path())), -4);
            }
            $modif = date(FM_DATETIME_FORMAT, $modif_raw);
            $date_sorting = strtotime(date("F d Y H:i:s.", $modif_raw));

            if (!is_string($f)) {
                $fobj = $f;
                $f = $fname;
            }

            $html .= '<tr>';
            if (!FM_READONLY) {
                $html .= '<td class="custom-checkbox-td">';
                $html .= '<div class="custom-control custom-checkbox">';
                $html .= "<input type='checkbox' class='custom-control-input' id='{$ii}' name='file[]' value='{$this->fm_enc($fobj->path())}' data-dir>";
                $html .= "<label class='custom-control-label' for='{$ii}'></label>";
                $html .= '</div>';
                $html .= '</td>';
            }

            /**
             * FILENAME
             */
            if (!ROOT_DIR) {
                $html .= "<td data-sort='{$this->fm_convert_win($this->fm_enc($f))}'>";
                $html .= '<div class="filename">';
                $uri1 = urlencode(trim(FM_PATH . '/' . $f, '/')) . $set_id;
                $html .= "<a href='?p={$uri1}'><i class='{$img}'></i>&nbsp;{$this->fm_convert_win($this->fm_enc($f))}";
                $link = ($is_link ? ' &rarr; <i>' . readlink($path . '/' . $f) . '</i>' : '');
                $html .= "</a>{$link}</div>";
                $html .= '</td>';
            } else {
                $html .= "<td data-sort='{$this->fm_convert_win($this->fm_enc($f))}'>";
                $html .= '<div class="filename">';
                $uri1 = urlencode(trim(FM_PATH . '/' . $f, '/')) . $set_id;
                $html .= "<a href='?p={$uri1}'><i class='{$img}'></i>&nbsp;";
                $html .= ($i == 0 ? 'Estate only documents' : 'Publicly viewable files');
                $i++;
                $html .= "</a></div>";
                $html .= '</td>';
            }

            // /**
            //  * DETAILS
            //  */
            // if (!FM_READONLY && ROOT_DIR) {
            //     $html .= "<td>";
            //     $html .= $i == 0 ? 'Estate only documents' : 'Publicly viewable files';
            //     $i++;
            //     $html .= "</td>";
            // }

            /**
             * FILE SIZE
             */
            $data1 = str_pad($filesize_raw, 18, "0", STR_PAD_LEFT);
            $html .= "<td data-order='a-{$data1}'>";
            $html .= $filesize;
            $html .= '</td>';

            /**
             * MODIFIED
             */
            $html .= "<td data-order='a-{$date_sorting}'>{$modif}</td>";

            /**
             * ACTIONS
             */
            if (!FM_READONLY && !ROOT_DIR) {
                $html .= '<td class="inline-actions">';
                $uri1 = urlencode($fobj->path());
                $html .= "<a title='{$this->lng('Delete')}' href='/personal-documents/delete?file={$uri1}&dir=1' data-del-dir='{$uri1}'>";
                $html .= '<i class="fa fa-trash-o" aria-hidden="true"></i></a>&nbsp;';
                $html .= "<a title='{$this->lng('Rename')}' href='javascript:void(0)' data-rename data-f-path='{$uri1}' data-f='{$this->fm_enc(addslashes($f))}'>";
                $html .= '<i class="fa fa-pencil-square-o" aria-hidden="true"></i></a>&nbsp;';
                $html .= '</td>';
            }
            $html .= '</tr>';
            $ii++;
        }

        /**
         * FILES
         */
        $ik = 6070;
        foreach ($files as $fname => $f) {
            if (isset($this->file_path)) {
                // Standard File Path
                $is_link = is_link($path . '/' . $f);
                $img = $is_link ? 'fa fa-file-text-o' : $this->fm_get_file_icon_class($path . '/' . $f);
                $modif_raw = filemtime($path . '/' . $f);
                $filesize_raw = $this->fm_get_size($path . '/' . $f);
                // $perms = substr(decoct(fileperms($path . '/' . $f)), -4);
                // if (function_exists('posix_getpwuid') && function_exists('posix_getgrgid')) {
                //     $owner = posix_getpwuid(fileowner($path . '/' . $f));
                //     $group = posix_getgrgid(filegroup($path . '/' . $f));
                //     if ($owner === false) {
                //         $owner = array('name' => '?');
                //     }
                //     if ($group === false) {
                //         $group = array('name' => '?');
                //     }
                // } else {
                //     $owner = array('name' => '?');
                //     $group = array('name' => '?');
                // }
            } else {
                // File over FTP
                $is_link = is_link($f->path());
                $img = $is_link ? 'fa fa-file-text-o' : $this->fm_get_file_icon_class($f->path());
                $modif_raw = $f->lastModified();
                $filesize_raw = $f->fileSize();
            }
            $modif = date(FM_DATETIME_FORMAT, $modif_raw);
            $date_sorting = strtotime(date("F d Y H:i:s.", $modif_raw));
            if (is_string($f)) {
                $fname = $f;
            }
            $filesize = $this->fm_get_filesize($filesize_raw);
            if (isset($this->file_path)) {
                $filelink = '?p=' . urlencode(FM_PATH) . '&amp;view=' . urlencode($fname) . $set_id;
            } else {
                $filelink = '?p=' . urlencode(FM_PATH) . '&amp;view=' . urlencode($f->path()) . $set_id;
                $file_url = $this->fm_enc($this->ftp_url . $f->path());
            }
            $all_files_size += (float) $filesize_raw;


            $html .= '<tr>';
            if (!FM_READONLY) {
                $html .= '<td class="custom-checkbox-td">';
                $html .= '<div class="custom-control custom-checkbox">';
                $html .= "<input type='checkbox' class='custom-control-input' id='{{$ik}' name='file[]' value='{$this->fm_enc($f->path())}' data-file>";
                $html .= "<label class='custom-control-label' for='{$ik}'></label>";
                $html .= '</div>';
                $html .= '</td>';
            }

            /**
             * FILE NAME
             */
            $html .= "<td data-sort='{$this->fm_enc($fname)}'>";
            $html .= '<div class="filename">';
            if (!FM_READONLY) {
                $html .= "<a href='{$file_url}' title='{$fname}' target='_blank' rel='no-opener'>";
            } else {
                $html .= "<a href='{$file_url}' title='{$fname}' target='_blank' rel='no-opener'>";
            }
            $html .= "<i class='{$img}'></i>";
            $html .= $this->fm_convert_win($this->fm_enc($fname));
            $html .= '</a>';
            $html .= ($is_link ? ' &rarr; <i>' . readlink($path . '/' . $fname) . '</i>' : '');
            $html .= '</div>';
            $html .= '</td>';

            /**
             * SIZE
             */
            $order = str_pad($filesize_raw, 18, "0", STR_PAD_LEFT);
            $html .= "<td data-order='b-{$order}'><span title='";
            $html .= sprintf('%s bytes', $filesize_raw);
            $html .= "'>";
            $html .= $filesize;
            $html .= '</span></td>';
            /**
             * DATE MODIFIED
             */
            $html .= "<td data-order='b-{$date_sorting}'>{$modif}</td>";

            if (!FM_READONLY) {
                $html .= '<td class="inline-actions">';
                $uri1 = urlencode($f->path());
                $html .= "<a title='{$this->lng('Delete')}' href='/personal-documents/delete?file={$uri1}' data-del-file='{$uri1}'> <i class='fa fa-trash-o'></i></a>&nbsp;";
                $html .= "<a title='{$this->lng('Rename')}' href='javascript:void(0)' data-rename data-f-path='{$uri1}' data-f='{$this->fm_enc(addslashes($fname))}'>";
                $html .= "<i class='fa fa-pencil-square-o'></i></a>&nbsp;";
                if (isset($this->file_path)) {
                    $html .= "<a title='{$this->lng('DirectLink')}' href='{$this->fm_enc(FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' .$fname)}' target='_blank'><i class='fa fa-link'></i></a>&nbsp;";
                } else {
                    $html .= "<a title='{$this->lng('DirectLink')}' href='{$file_url}' target='_blank'><i class='fa fa-link'></i></a>&nbsp;";
                }
                $uri1 = urlencode($f->path());
                $html .= "<a title='{$this->lng('Download')}' href='/personal-documents/download?file={$uri1}' target='_blank' rel='no-opener'><i class='fa fa-download'></i></a>";
                $html .= "</td>";
            }
            $html .= "</tr>";
            $ik++;
        }

        if (empty($folders) && empty($files)) {
            $html .= '<tfoot>';
            $html .= '<tr>';
            if (!FM_READONLY) {
                $html .= '<td></td>';
            }
            $colspan = FM_READONLY ? 3 : 4;
            $html .= "<td colspan='{$colspan}'><em>Folder is empty</em></td>";
            $html .= '</tr>';
            $html .= '</tfoot>';
        } else {
            $html .= '<tfoot>';
            $html .= '<tr>';
            $colspan = FM_READONLY ? 3 : 4;
            $html .= "<td class='gray' colspan='{$colspan}'>";
            $html .= 'Total Size: <span class="badge text-bg-light border-radius-0">' . $this->fm_get_filesize($all_files_size) . '</span>&nbsp;';
            $html .= 'Files: <span class="badge text-bg-light border-radius-0">' . $num_files . '</span>&nbsp;';
            $html .= 'Folders: <span class="badge text-bg-light border-radius-0">' . $num_folders . '</span>&nbsp;';
            $html .= '</td>';
            $html .= '</tr>';
            $html .= '</tfoot>';
        }
        $html .= '</table>';
        $html .= '</div>';
        $html .= '<div class="row">';
        if (!FM_READONLY) {
            $html .= '<div class="col-xs-12 col-sm-9">';
            $html .= '<ul class="list-inline footer-action">';
            $html .= "<li class='list-inline-item'>&nbsp;";
            $html .= "<button type='button' class='btn btn-small btn-outline-primary btn-2' id='fm_select_all'>";
            $html .= "<i class='fa fa-check-square'></i>&nbsp;{$this->lng('SelectAll')}&nbsp;</button></li>";
            $html .= "<li class='list-inline-item'>";
            $html .= "<button type='button' class='btn btn-small btn-outline-primary btn-2' id='fm_unselect_all'>";
            $html .= "<i class='fa fa-window-close'></i>&nbsp;{$this->lng('UnSelectAll')}&nbsp;</button></li>";
            $html .= "<li class='list-inline-item'>";
            $html .= "<button type='button' class='btn btn-small btn-outline-primary btn-2' id='fm_invert_all'>";
            $html .= "<i class='fa fa-th-list'></i>&nbsp;{$this->lng('InvertSelection')}&nbsp;</button></li>";
            $html .= "<li class='list-inline-item'>";
            $csrf = Yii::$app->request->csrfToken;
            $html .= "<button type='button' class='btn btn-small btn-outline-primary btn-2' id='fm_delete_all' data-csrf='{$csrf}'>";
            $html .= "<i class='fa fa-trash'></i>&nbsp;{$this->lng('Delete Selected')}&nbsp;</button>";
            $html .= "</li>";
            $html .= "</ul>";
            $html .= "</div>";
        }
        $html .= '</div>';
        $html .= '</form>';

        $html .= $this->fm_show_footer();
        return $html;
    }


    protected function upload_form() {
        $set_id = isset($_GET['id']) && !empty($_GET['id']) ? "&id={$_GET['id']}" : '';
        $html = $this->init_html();
        $html .= $this->fm_show_header(); // HEADER
        $html .= $this->fm_show_nav_path(FM_PATH); // current path
        //get the allowed file extensions
        function getUploadExt() {
            $extArr = explode(',', FM_UPLOAD_EXTENSION);
            if (FM_UPLOAD_EXTENSION && $extArr) {
                array_walk($extArr, function (&$x) {
                    $x = ".{$x}";
                });
                return implode(',', $extArr);
            }
            return '';
        }
        $html .= $this->print_external('css-dropzone', true);
        $html .= '<div class="path">';

        $html .= "<div class='card mb-2 fm-upload-wrapper {$this->fm_get_theme()}'>";

        $html .= '<div class="card-body">';
        $html .= '<p class="card-text">';
        $path = FM_PATH . $set_id;
        $html .= "<a href='?p={$path}' class='float-right'>";
        $html .= "<i class='fa fa-chevron-circle-left go-back'></i>&nbsp;{$this->lng('Back')}</a>";
        $html .= "<strong>{$this->lng('DestinationFolder')}</strong>: {$this->fm_enc($this->fm_convert_win(FM_PATH))}";
        $html .= '</p>';

        $html .= "<script>" . <<<JS
        Dropzone.options.fileUploader = {
            chunking: true,
            chunkSize: 2000000,
            forceChunking: false,
            retryChunks: false,
            retryChunksLimit: 3,
            parallelUploads: 3,
            parallelChunkUploads: false,
            timeout: 120000,
            maxFilesize: 5000000000,
            init: function () {
                this.on("sending", function (file, xhr, formData) {
                    let _path = (file.fullPath) ? file.fullPath : file.name;
                    document.getElementById("fullpath").value = _path;
                    xhr.ontimeout = (function () {
                        console.warn('Error: Server Timeout');
                    });
                }).on("success", function (res) {
                    let _response = JSON.parse(res.xhr.response);
                    if (_response.status == "error") {
                        console.log(_response.info);
                    }
                }).on("error", function (file, response) {
                    console.error(response);
                });
            }
        };
        JS . '</script>';

        $html .= "<form action='/personal-documents/upload' id='fileUploader' class='dropzone' enctype='multipart/form-data'>";
        $html .= "<input type='hidden' name='p' value='{$this->fm_enc(FM_PATH)}'>";
        $html .= "<input type='hidden' name='fullpath' id='fullpath' value='{$this->fm_enc(FM_PATH)}'>";
        $html .= "<input type='hidden' name='selected_estate' id='selected_estate' value='{$this->selected_estate}'>";
        $html .= "<input type='hidden' name='token' value='{$_SESSION['token']}'>";
        $csrf = Yii::$app->request->csrfToken;
        $html .= "<input type='hidden' name='{$this->csrfToken}' value='{$csrf}'>";
        $html .= '</form>';

        $html .= '</div>';
        $html .= '</form>';
        $html .= '<div id="js-url-upload__list" class="col-9 mt-3"></div>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= $this->fm_show_footer();
        return $html;
    }


    protected function copy_form_post() {
        $copy_files = isset($_POST['file']) ? $_POST['file'] : null;
        if (!is_array($copy_files) || empty($copy_files)) {
            $this->fm_set_msg($this->lng('Nothing selected'), 'alert');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }
        $this->fm_show_header(); // HEADER
        $this->fm_show_nav_path(FM_PATH); // current path
?>
        <div class="path">
            <div class="card <?php echo $this->fm_get_theme(); ?>">
                <div class="card-header">
                    <h6><?php echo $this->lng('Copying') ?></h6>
                </div>
                <div class="card-body">
                    <form action="" method="post">
                        <input type="hidden" name="p" value="<?php echo $this->fm_enc(FM_PATH) ?>">
                        <input type="hidden" name="finish" value="1">
                        <?php
                        foreach ($copy_files as $cf) {
                            echo '<input type="hidden" name="file[]" value="' . $this->fm_enc($cf) . '">' . PHP_EOL;
                        }
                        ?>
                        <p class="break-word"><strong><?php echo $this->lng('Files') ?></strong>: <b><?php echo implode('</b>, <b>', $copy_files) ?></b></p>
                        <p class="break-word"><strong><?php echo $this->lng('SourceFolder') ?></strong>: <?php echo $this->fm_enc($this->fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH)) ?><br>
                            <label for="inp_copy_to"><strong><?php echo $this->lng('DestinationFolder') ?></strong>:</label>
                            <?php echo FM_ROOT_PATH ?>/<input type="text" name="copy_to" id="inp_copy_to" value="<?php echo $this->fm_enc(FM_PATH) ?>">
                        </p>
                        <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 ms-2"> <?php echo $this->lng('Move') ?></label></p>
                        <p>
                            <b><a href="?p=<?php echo urlencode(FM_PATH) ?>" class="btn btn-outline-danger"><i class="fa fa-times-circle"></i> <?php echo $this->lng('Cancel') ?></a></b>&nbsp;
                            <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
                            <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo $this->lng('Copy') ?></button>
                        </p>
                    </form>
                </div>
            </div>
        </div>
    <?php
        $this->fm_show_footer();
        exit;
    }


    protected function copy_form($parent, $folders) {
        $html = $this->init_html();
        $copy = $_GET['copy'];
        $copy = $this->fm_clean_path($copy);
        if ($copy == '' || !file_exists(FM_ROOT_PATH . '/' . $copy)) {
            $this->fm_set_msg($this->lng('File not found'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }

        $html .= $this->fm_show_header(); // HEADER
        $html .= $this->fm_show_nav_path(FM_PATH); // current path

        $html .= '<div class="path">';
        $html .= '<p><b>Copying</b></p>';
        $html .= '<p class="break-word">';
        $html .= "<strong>Source path:</strong>&nbsp;{$this->fm_enc($this->fm_convert_win(FM_ROOT_PATH . '/' .$copy))}<br>";
        $html .= "<strong>Destination folder:</strong>&nbsp;" . $this->fm_enc($this->fm_convert_win(FM_ROOT_PATH . '/' . FM_PATH));
        $html .= '</p>';
        $html .= '<p>';
        $path = urlencode(FM_PATH);
        $copy_uri = urlencode($copy);
        $html .= "<b><a href='?p={$path}&amp;copy={$copy_uri}&amp;finish=1'><i class='fa fa-check-circle'></i> Copy</a></b> &nbsp;";
        $html .= "<b><a href='?p={$path}&amp;copy={$copy_uri}&amp;finish=1&amp;move=1'><i class='fa fa-check-circle'></i> Move</a></b> &nbsp;";
        $html .= "<b><a href='?p={$path}' class='text-danger'><i class='fa fa-times-circle'></i> Cancel</a></b>";
        $html .= '</p>';
        $html .= "<p><i>{$this->lng('Select folder')}</i></p>";
        $html .= '<ul class="folders break-word">';

        if ($parent !== false) {
            $parent = urlencode($parent);
            $html .= "<li><a href='?p={$parent}&amp;copy={$copy_uri}'><i class='fa fa-chevron-circle-left'></i> ..</a></li>";
        }
        foreach ($folders as $f) {
            $html .= '<li>';
            $uri = urlencode(trim(FM_PATH . '/' . $f, '/'));
            $html .= "<a href='?p={$uri}&amp;copy={$copy_uri}'><i class='fa fa-folder-o'></i>&nbsp;{$this->fm_convert_win($f)}</a>";
            $html .= '</li>';
        }
        $html .= '</ul>';
        $html .= '</div>';
        $html .= $this->fm_show_footer();
        return $html;
    }


    protected function view_file_form($path) {
        $file = $_GET['view'];
        $file = $this->fm_clean_path($file, false);
        if (isset($this->file_path)) {
            $file = str_replace('/', '', $file);
            if (empty($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));
            }
        } else {
            if (empty($file) || !$this->ftp_filesystem->fileExists($file)) {
                $this->fm_set_msg($this->lng('File not found'), 'error');
                $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
            }
        }

        $html = $this->init_html();

        $html .= $this->fm_show_header(); // HEADER
        $html .= $this->fm_show_nav_path(FM_PATH); // current path

        if (isset($this->file_path)) {
            $file_url = $this->fm_enc(FM_ROOT_URL . $this->fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file));
            $file_path = $path . '/' . $file;

            $mime_type = $this->fm_get_mime_type($file_path);
            $filesize_raw = $this->fm_get_size($file_path);
        } else {
            $file_url = $this->fm_enc($this->ftp_url . $file);
            $file_path = $file;

            $mime_type = $this->ftp_filesystem->mimeType($file_path);
            $filesize_raw = $this->ftp_filesystem->fileSize($file_path);
        }
        $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
        $filesize = $this->fm_get_filesize($filesize_raw);

        $is_zip = false;
        $is_gzip = false;
        $is_image = false;
        $is_audio = false;
        $is_video = false;
        $is_text = false;
        $is_onlineViewer = false;

        $view_title = 'File';
        $filenames = false; // for zip
        $content = ''; // for text
        $online_viewer = strtolower(FM_DOC_VIEWER);

        if ($online_viewer && $online_viewer !== 'false' && in_array($ext, $this->fm_get_onlineViewer_exts())) {
            $is_onlineViewer = true;
        } elseif ($ext == 'zip' || $ext == 'tar') {
            $is_zip = true;
            $view_title = 'Archive';
            $filenames = $this->fm_get_zif_info($file_path, $ext);
        } elseif (in_array($ext, $this->fm_get_image_exts())) {
            $is_image = true;
            $view_title = 'Image';
        } elseif (in_array($ext, $this->fm_get_audio_exts())) {
            $is_audio = true;
            $view_title = 'Audio';
        } elseif (in_array($ext, $this->fm_get_video_exts())) {
            $is_video = true;
            $view_title = 'Video';
        } elseif (in_array($ext, $this->fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, $this->fm_get_text_mimes())) {
            $is_text = true;
            if (isset($this->file_path)) {
                $content = file_get_contents($file_path);
            } else {
                $size = (int)$this->ftp_filesystem->fileSize($file);
                $content = '';
                if ($size < 10000) {
                    $content = file_get_contents($file_url);
                } else if ($size < 100000) {
                    $readfile = $this->ftp_filesystem->readStream($file);
                    // Read the first 1000 characters
                    $content = fread($readfile, 10000);
                    $content .= "...\n\nFile too big, please download the file to view the whole thing.";
                    fclose($readfile); // Close the file
                } else {
                    /**
                     * @note    This takes bloody ages to load for a file ~25mb, ymmv
                     */
                    $content = 'File too big, please download the file to view the whole thing.';
                }
            }
        }

        $html .= '<div class="row">';
        $html .= '<div class="col-12">';
        $display_path = $this->fm_get_display_path($file_path);
        if (isset($this->file_path)) {
            $set_view_filename = $this->fm_enc($this->fm_convert_win($file));
            $set_display_path = $display_path['path'];
        } else {
            $parts = explode("/", $file);
            $set_view_filename = '"' . array_reverse($parts)[0] . '"';
            array_shift($parts);
            $set_display_path = '/' . implode("/", $parts);
        }
        $html .= "<p class='break-word'><b>{$this->lng($view_title)} {$set_view_filename}</b></p>";
        $html .= '<p class="break-word">';
        $html .= "<strong>{$display_path['label']}:</strong> {$set_display_path}<br>";
        $size = ($filesize_raw <= 1000) ? "{$filesize_raw} bytes" : $filesize;
        $html .= "<strong>File size:</strong> {$size}<br>";
        $html .= "<strong>MIME-type:</strong> {$mime_type}<br>";
        // ZIP info
        if (($is_zip || $is_gzip) && $filenames !== false) {
            $total_files = 0;
            $total_comp = 0;
            $total_uncomp = 0;
            foreach ($filenames as $fn) {
                if (!$fn['folder']) {
                    $total_files++;
                }
                $total_comp += $fn['compressed_size'];
                $total_uncomp += $fn['filesize'];
            }
            $html .= "{$this->lng('Files in archive')}: {$total_files}<br>";
            $html .= "{$this->lng('Total size')}: {$this->fm_get_filesize($total_uncomp)}<br>";
            $html .= "{$this->lng('Size in archive')}: {$this->fm_get_filesize($total_comp)}<br>";
            $compression = round(($total_comp / max($total_uncomp, 1)) * 100);
            $html .= "{$this->lng('Compression')}: {$compression}%<br>";
        }
        // Image info
        if ($is_image) {
            if (isset($this->file_path)) {
                $image_size = getimagesize($file_path);
            } else {
                $image_size = getimagesize($file_url);
            }
            $html .= '<strong>' . $this->lng('Image size') . ':</strong> ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '<br>';
        }
        // Text info
        if ($is_text) {
            $is_utf8 = $this->fm_is_utf8($content);
            if (function_exists('iconv')) {
                if (!$is_utf8) {
                    $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content);
                }
            }
            $html .= '<strong>' . $this->lng('Charset') . ':</strong> ' . ($is_utf8 ? 'utf-8' : '8 bit') . '<br>';
        }

        $html .= '</p>';
        // $html .= '<div class="d-flex align-items-center mb-3">';
        $html .= '<div class="fm_action_buttons">';
        /**
         * DOWNLOAD
         */
        $site = urlencode(FM_PATH);
        $file_uri = urlencode($file);

        if (isset($this->file_path)) {
            $action = "?p={$site}&amp;dl={$file_uri}";
        } else {
            $action = "/personal-documents/download?file={$file_uri}";
        }


        $html .= "<form method='post' class='ms-2' action='{$action}' target='_blank'>";
        $csrf = Yii::$app->request->csrfToken;
        $html .= "<input type='hidden' name='{$this->csrfToken}' value='{$csrf}'>";
        $html .= "<input type='hidden' name='token' value='{$_SESSION['token']}'>";
        $html .= "<button type='submit' class='btn btn-link text-decoration-none fw-bold p-0' style='padding:0; text-decoration:none;'>";
        $html .= "<i class='fa fa-cloud-download'></i>&nbsp<b>{$this->lng('Download')}</b></button>";
        $html .= '</form>';
        /**
         * OPEN
         */
        $html .= "<b class='ms-2'><a href='{$file_url}' target='_blank'>";
        $html .= "<i class='fa fa-external-link-square'></i>&nbsp;{$this->lng('Open')}</a></b>";
        // ZIP actions
        if (!FM_READONLY && ($is_zip || $is_gzip) && $filenames !== false) {
            $zip_name = pathinfo($file_path, PATHINFO_FILENAME);
            $html .= '<form method="post" class="d-inline ms-2">';
            $csrf = Yii::$app->request->csrfToken;
            $html .= "<input type='hidden' name='{$this->csrfToken}' value='{$csrf}'>";
            $html .= "<input type='hidden' name='token' value='{$_SESSION['token']}'>";
            $file_val = urlencode($file);
            $html .= "<input type='hidden' name='unzip' value='{$file_val}'>";
            $html .= "<button type='submit' class='btn btn-link text-decoration-none fw-bold p-0' style='font-size: 14px;'>";
            $html .= "<i class='fa fa-check-circle'></i>&nbsp;{$this->lng('UnZip')}</button>";
            $html .= '</form>&nbsp;';
            $html .= '<form method="post" class="d-inline ms-2">';
            $csrf = Yii::$app->request->csrfToken;
            $html .= "<input type='hidden' name='{$this->csrfToken}' value='{$csrf}'>";
            $html .= "<input type='hidden' name='token' value='{$_SESSION['token']}'>";
            $html .= "<input type='hidden' name='unzip' value='{$file_val}'>";
            $html .= '<input type="hidden" name="tofolder" value="1">';
            $html .= "<button type='submit' class='btn btn-link text-decoration-none fw-bold p-0' style='font-size: 14px;' title='UnZip to {$this->fm_enc($zip_name)}'>";
            $html .= "<i class='fa fa-check-circle'></i>&nbsp;{$this->lng('UnZipToFolder')}</button>";
            $html .= '</form>&nbsp;';
        }
        if ($is_text && !FM_READONLY) {
            $uri_href = urlencode(trim(FM_PATH));
            $uri_file = urlencode($file);

            // /**
            //  * EDIT
            //  */
            // $html .= "<b class='ms-2'><a href='?p={$uri_href}&amp;edit={$uri_file}' class='edit-file'>";
            // $html .= "<i class='fa fa-pencil-square'></i>&nbsp;{$this->lng('Edit')}</a></b> &nbsp;";

            // /**
            //  * EDIT WITH ACE
            //  */
            // $html .= "<b class='ms-2'><a href='?p={$uri_href}&amp;edit={$uri_file}&env=ace' class='edit-file'>";
            // $html .= "<i class='fa fa-pencil-square-o'></i>&nbsp;{$this->lng('AdvancedEditor')}</a></b> &nbsp;";
        }
        /**
         * BACK
         */
        $uri1 = urlencode(FM_PATH);
        $html .= "<b class='ms-2'><a href='?p={$uri1}'><i class='fa fa-chevron-circle-left go-back'></i>&nbsp;{$this->lng('Back')}</a></b>";
        $html .= '</div>';

        /**
         * View File
         */
        if ($is_onlineViewer) {
            if ($online_viewer == 'google') {
                $html .= '<iframe src="https://docs.google.com/viewer?embedded=true&hl=en&url=' . $file_url . '" frameborder="no" style="width:100%;min-height:460px"></iframe>';
            } else if ($online_viewer == 'microsoft') {
                $html .= '<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=' . $file_url . '" frameborder="no" style="width:100%;min-height:460px"></iframe>';
            }
        } else if ($is_zip) {
            // ZIP content
            if ($filenames !== false) {
                $html .= '<code class="maxheight">';
                foreach ($filenames as $fn) {
                    if ($fn['folder']) {
                        $html .= '<b>' . $this->fm_enc($fn['name']) . '</b><br>';
                    } else {
                        $html .= $fn['name'] . ' (' . $this->fm_get_filesize($fn['filesize']) . ')<br>';
                    }
                }
                $html .= '</code>';
            } else {
                $html .= '<p>' . $this->lng('Error while fetching archive info') . '</p>';
            }
        } else if ($is_image) {
            // Image content
            if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))) {
                $html .= '<p>';
                $html .= '<input type="checkbox" id="preview-img-zoomCheck">';
                $html .= '<label for="preview-img-zoomCheck">';
                $html .= '<img src="' . $file_url . '" alt="image" class="preview-img">';
                $html .= '</label></p>';
            }
        } elseif ($is_audio) {
            // Audio content
            $html .= '<p><audio src="' . $file_url . '" controls preload="metadata"></audio></p>';
        } else if ($is_video) {
            // Video content
            $html .= '<div class="preview-video"><video src="' . $file_url . '" width="640" height="360" controls preload="metadata"></video></div>';
        } else if ($is_text) {
            if (FM_USE_HIGHLIGHTJS) {
                // highlight
                $hljs_classes = [
                    'shtml' => 'xml',
                    'htaccess' => 'apache',
                    'phtml' => 'php',
                    'lock' => 'json',
                    'svg' => 'xml',
                ];
                $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext;
                if (empty($ext) || in_array(strtolower($file), $this->fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) {
                    $hljs_class = 'nohighlight';
                }
                $content = '<pre class="with-hljs"><code class="' . $hljs_class . '">' . $this->fm_enc($content) . '</code></pre>';
            } else if (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) {
                // php highlight
                $content = highlight_string($content, true);
            } else {
                $content = '<pre>' . $this->fm_enc($content) . '</pre>';
            }
            $html .= $content;
        }
        $html .= '</div>';
        $html .= '</div>';
        $html .= $this->fm_show_footer();
        return $html;
    }


    protected function file_editor_form($path) {
        $file = $_GET['edit'];
        $file = $this->fm_clean_path($file, false);
        $file = str_replace('/', '', $file);
        if ($file == '' || !is_file($path . '/' . $file) || in_array($file, $GLOBALS['exclude_items'])) {
            $this->fm_set_msg($this->lng('File not found'), 'error');
            $this->fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
        }
        $editFile = ' : <i><b>' . $file . '</b></i>';
        header('X-XSS-Protection:0');
        $this->fm_show_header(); // HEADER
        $this->fm_show_nav_path(FM_PATH); // current path

        $file_url = FM_ROOT_URL . $this->fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file);
        $file_path = $path . '/' . $file;

        // normal editer
        $isNormalEditor = true;
        if (isset($_GET['env'])) {
            if ($_GET['env'] == "ace") {
                $isNormalEditor = false;
            }
        }

        // Save File
        if (isset($_POST['savedata'])) {
            $writedata = $_POST['savedata'];
            $fd = fopen($file_path, "w");
            @fwrite($fd, $writedata);
            fclose($fd);
            $this->fm_set_msg($this->lng('File Saved Successfully'));
        }

        $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
        $mime_type = $this->fm_get_mime_type($file_path);
        $filesize = filesize($file_path);
        $is_text = false;
        $content = ''; // for text

        if (in_array($ext, $this->fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, $this->fm_get_text_mimes())) {
            $is_text = true;
            $content = file_get_contents($file_path);
        }

    ?>
        <div class="path">
            <div class="row">
                <div class="col-xs-12 col-sm-5 col-lg-6 pt-1">
                    <div class="btn-toolbar" role="toolbar">
                        <?php if (!$isNormalEditor) { ?>
                            <div class="btn-group js-ace-toolbar">
                                <button data-cmd="none" data-option="fullscreen" class="btn btn-sm btn-outline-secondary" id="js-ace-fullscreen" title="<?php echo $this->lng('Fullscreen') ?>"><i class="fa fa-expand" title="<?php echo $this->lng('Fullscreen') ?>"></i></button>
                                <button data-cmd="find" class="btn btn-sm btn-outline-secondary" id="js-ace-search" title="<?php echo $this->lng('Search') ?>"><i class="fa fa-search" title="<?php echo $this->lng('Search') ?>"></i></button>
                                <button data-cmd="undo" class="btn btn-sm btn-outline-secondary" id="js-ace-undo" title="<?php echo $this->lng('Undo') ?>"><i class="fa fa-undo" title="<?php echo $this->lng('Undo') ?>"></i></button>
                                <button data-cmd="redo" class="btn btn-sm btn-outline-secondary" id="js-ace-redo" title="<?php echo $this->lng('Redo') ?>"><i class="fa fa-repeat" title="<?php echo $this->lng('Redo') ?>"></i></button>
                                <button data-cmd="none" data-option="wrap" class="btn btn-sm btn-outline-secondary" id="js-ace-wordWrap" title="<?php echo $this->lng('Word Wrap') ?>"><i class="fa fa-text-width" title="<?php echo $this->lng('Word Wrap') ?>"></i></button>
                                <select id="js-ace-mode" data-type="mode" title="<?php echo $this->lng('Select Document Type') ?>" class="btn-outline-secondary border-start-0 d-none d-md-block">
                                    <option>-- <?php echo $this->lng('Select Mode') ?> --</option>
                                </select>
                                <select id="js-ace-theme" data-type="theme" title="<?php echo $this->lng('Select Theme') ?>" class="btn-outline-secondary border-start-0 d-none d-lg-block">
                                    <option>-- <?php echo $this->lng('Select Theme') ?> --</option>
                                </select>
                                <select id="js-ace-fontSize" data-type="fontSize" title="<?php echo $this->lng('Select Font Size') ?>" class="btn-outline-secondary border-start-0 d-none d-lg-block">
                                    <option>-- <?php echo $this->lng('Select Font Size') ?> --</option>
                                </select>
                            </div>
                        <?php } ?>
                    </div>
                </div>
                <div class="edit-file-actions col-xs-12 col-sm-7 col-lg-6 text-end pt-1">
                    <a title="<?php echo $this->lng('Back') ?>" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&amp;view=<?php echo urlencode($file) ?>"><i class="fa fa-reply-all"></i> <?php echo $this->lng('Back') ?></a>
                    <a title="<?php echo $this->lng('BackUp') ?>" class="btn btn-sm btn-outline-primary" href="javascript:void(0);" onclick="backup('<?php echo urlencode(trim(FM_PATH)) ?>','<?php echo urlencode($file) ?>')"><i class="fa fa-database"></i> <?php echo $this->lng('BackUp') ?></a>
                    <?php if ($is_text) { ?>
                        <?php if ($isNormalEditor) { ?>
                            <a title="Advanced" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&amp;edit=<?php echo urlencode($file) ?>&amp;env=ace"><i class="fa fa-pencil-square-o"></i> <?php echo $this->lng('AdvancedEditor') ?></a>
                            <button type="button" class="btn btn-sm btn-success" name="Save" data-url="<?php echo $this->fm_enc($file_url) ?>" onclick="edit_save(this,'nrl')"><i class="fa fa-floppy-o"></i> Save
                            </button>
                        <?php } else { ?>
                            <a title="Plain Editor" class="btn btn-sm btn-outline-primary" href="?p=<?php echo urlencode(trim(FM_PATH)) ?>&amp;edit=<?php echo urlencode($file) ?>"><i class="fa fa-text-height"></i> <?php echo $this->lng('NormalEditor') ?></a>
                            <button type="button" class="btn btn-sm btn-success" name="Save" data-url="<?php echo $this->fm_enc($file_url) ?>" onclick="edit_save(this,'ace')"><i class="fa fa-floppy-o"></i> <?php echo $this->lng('Save') ?>
                            </button>
                        <?php } ?>
                    <?php } ?>
                </div>
            </div>
            <?php
            if ($is_text && $isNormalEditor) {
                echo '<textarea class="mt-2" id="normal-editor" rows="33" cols="120" style="width: 99.5%;">' . htmlspecialchars($content) . '</textarea>';
                echo '<script>document.addEventListener("keydown", function(e) {if ((window.navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.keyCode == 83) { e.preventDefault();edit_save(this,"nrl");}}, false);</script>';
            } elseif ($is_text) {
                echo '<div id="editor" contenteditable="true">' . htmlspecialchars($content) . '</div>';
            } else {
                $this->fm_set_msg($this->lng('FILE EXTENSION HAS NOT SUPPORTED'), 'error');
            }
            ?>
        </div>
    <?php
        $this->fm_show_footer();
        exit;
    }


    protected function chmod_form($path) {
        $file = $_GET['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));
        }

        $this->fm_show_header(); // HEADER
        $this->fm_show_nav_path(FM_PATH); // current path

        $file_url = FM_ROOT_URL . (FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file;
        $file_path = $path . '/' . $file;

        $mode = fileperms($path . '/' . $file);
    ?>
        <div class="path">
            <div class="card mb-2 <?php echo $this->fm_get_theme(); ?>">
                <h6 class="card-header">
                    <?php echo $this->lng('ChangePermissions') ?>
                </h6>
                <div class="card-body">
                    <p class="card-text">
                        <?php $display_path = $this->fm_get_display_path($file_path); ?>
                        <?php echo $display_path['label']; ?>: <?php echo $display_path['path']; ?><br>
                    </p>
                    <form action="" method="post">
                        <input type="hidden" name="p" value="<?php echo $this->fm_enc(FM_PATH) ?>">
                        <input type="hidden" name="chmod" value="<?php echo $this->fm_enc($file) ?>">

                        <table class="table compact-table <?php echo $this->fm_get_theme(); ?>">
                            <tr>
                                <td></td>
                                <td><b><?php echo $this->lng('Owner') ?></b></td>
                                <td><b><?php echo $this->lng('Group') ?></b></td>
                                <td><b><?php echo $this->lng('Other') ?></b></td>
                            </tr>
                            <tr>
                                <td style="text-align: right"><b><?php echo $this->lng('Read') ?></b></td>
                                <td><label><input type="checkbox" name="ur" value="1" <?php echo ($mode & 00400) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="gr" value="1" <?php echo ($mode & 00040) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="or" value="1" <?php echo ($mode & 00004) ? ' checked' : '' ?>></label></td>
                            </tr>
                            <tr>
                                <td style="text-align: right"><b><?php echo $this->lng('Write') ?></b></td>
                                <td><label><input type="checkbox" name="uw" value="1" <?php echo ($mode & 00200) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="gw" value="1" <?php echo ($mode & 00020) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="ow" value="1" <?php echo ($mode & 00002) ? ' checked' : '' ?>></label></td>
                            </tr>
                            <tr>
                                <td style="text-align: right"><b><?php echo $this->lng('Execute') ?></b></td>
                                <td><label><input type="checkbox" name="ux" value="1" <?php echo ($mode & 00100) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="gx" value="1" <?php echo ($mode & 00010) ? ' checked' : '' ?>></label></td>
                                <td><label><input type="checkbox" name="ox" value="1" <?php echo ($mode & 00001) ? ' checked' : '' ?>></label></td>
                            </tr>
                        </table>

                        <p>
                            <input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
                            <b><a href="?p=<?php echo urlencode(FM_PATH) ?>" class="btn btn-outline-primary"><i class="fa fa-times-circle"></i> <?php echo $this->lng('Cancel') ?></a></b>&nbsp;
                            <button type="submit" class="btn btn-success"><i class="fa fa-check-circle"></i> <?php echo $this->lng('Change') ?></button>
                        </p>
                    </form>
                </div>
            </div>
        </div>
<?php
        $this->fm_show_footer();
        exit;
    }
}
