<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');
ini_set('memory_limit', '-1');
// set max execution time 2 hours / mostly used for exporting PDF
ini_set('max_execution_time', 3600);

require_once(APPPATH . 'third_party/elfinder/autoload.php');

class Filemanager extends Client_Controller
{
    public function index()
    {
        $data['title'] = lang('filemanager');
        $data['breadcrumbs'] = lang('filemanager');
        $data['filemanager'] = true;
        $data['connector'] = base_url('client/filemanager/elfinder_init');
        $data['subview'] = $this->load->view('client/filemanager/filemanager', $data, TRUE);
        $this->load->view('client/_layout_main', $data); //page load
    }

    public function elfinder_init()
    {
        $this->load->helper('path');
        $_allowed_files = explode('|', config_item('allowed_files'));
        $config_allowed_files = array();
        if (is_array($_allowed_files)) {
            foreach ($_allowed_files as $v_extension) {
                array_push($config_allowed_files, '.' . $v_extension);
            }
        }
        $allowed_files = array();
        if (is_array($config_allowed_files)) {
            foreach ($config_allowed_files as $extension) {
                $_mime = get_mime_by_extension($extension);
                if ($_mime == 'application/x-zip') {
                    array_push($allowed_files, 'application/zip');
                }
                if ($extension == '.exe') {
                    array_push($allowed_files, 'application/x-executable');
                    array_push($allowed_files, 'application/x-msdownload');
                    array_push($allowed_files, 'application/x-ms-dos-executable');
                }
                array_push($allowed_files, $_mime);
            }
        }
        $root_options = array(
            'dispInlineRegex' => '^(?:image|application/(?:vnd\.)?(?:ms(?:-office|word|-excel|-powerpoint)|openxmlformats-officedocument)|text/plain$)',
            'driver' => 'LocalFileSystem',
            'path' => set_realpath('filemanager'),
            'URL' => site_url('filemanager') . '/',
            'uploadMaxSize' => config_item('max_file_size') . 'M',
            'accessControl' => 'access',
            'uploadDeny' => [
                'application/x-httpd-php',
                'application/php',
                'application/x-php',
                'text/php',
                'text/x-php',
                'application/x-httpd-php-source',
                'application/perl',
                'application/x-perl',
                'application/x-python',
                'application/python',
                'application/x-bytecode.python',
                'application/x-python-bytecode',
                'application/x-python-code',
                'wwwserver/shellcgi', // CGI
            ],
            'uploadAllow' => $allowed_files,
            'uploadOrder' => array(
                'allow',
                'deny'
            ),
            'attributes' => array(
                array(
                    'pattern' => '/.tmb/',
                    'hidden' => true
                ),
                array(
                    'pattern' => '/.quarantine/',
                    'hidden' => true
                )
            )
        );
        $client_info = $this->db->where('client_id', $this->session->userdata('client_id'))->get('tbl_client')->row();
        $user = $this->db->where('user_id', $this->session->userdata('user_id'))->get('tbl_users')->row();
        if (empty($client_info) || empty($user)) {
            show_error('Unable to initialize file manager.', 403);
        }

        $c_slug = $this->safe_media_slug($client_info->name, 'client-' . $client_info->client_id);
        $this->ensure_filemanager_directory('filemanager/' . $c_slug);
        if (empty($user->media_path_slug)) {
            $this->db->where('user_id', $user->user_id);
            $slug = $this->safe_media_slug($user->username, 'user-' . $user->user_id);
            $this->db->update('tbl_users', array(
                'media_path_slug' => $slug
            ));
            $user->media_path_slug = $slug;
        }
        $user_slug = $this->safe_media_slug($user->media_path_slug, 'user-' . $user->user_id);
        $c_path = $this->ensure_filemanager_directory('filemanager/' . $c_slug . '/' . $user_slug);
        array_push($root_options['attributes'], array(
            'pattern' => '/.(' . preg_quote($user_slug, '/') . '+)/', // Prevent deleting/renaming folder
            'read' => true,
            'write' => true,
            'locked' => true
        ));
        $root_options['path'] = $c_path;
        $root_options['URL'] = site_url('filemanager/' . $c_slug . '/' . $user_slug) . '/';
        $opts = array(
            'roots' => array(
                $root_options
            )
        );

        $connector = new elFinderConnector(new elFinder($opts));
        $connector->run();
    }

    private function safe_media_slug($value, $fallback)
    {
        $slug = trim((string) slug_it((string) $value));
        if ($slug === '') {
            $slug = trim((string) slug_it((string) $fallback));
        }
        return $slug !== '' ? $slug : 'files';
    }

    private function ensure_filemanager_directory($relative_path)
    {
        $path = set_realpath($relative_path);
        if (!is_dir($path)) {
            mkdir($path, 0755, true);
        }
        if (!file_exists($path . '/index.html')) {
            fclose(fopen($path . '/index.html', 'w'));
        }
        return set_realpath($relative_path);
    }
}
