<?php
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);

chdir('../..');
require_once('api/buyers.php');

const UPLOAD_DIR = 'files/uploads/';
const CREATED_BY = 'site-77.ru';
const ALLOWED = array("ffd8ff" => "jpg", "89504e" => "png", "474946" => "gif", "255044" => "pdf", "504B03" => "xlsx", "D0CF11" => "xls");

function delTree($dir)
{
    $files = array_diff(scandir($dir), array('.','..'));
    foreach ($files as $file)
        is_dir($dir."/".$file) ? delTree($dir."/".$file) : unlink($dir."/".$file);
    return rmdir($dir);
}

function exit_json($response)
{
    exit(json_encode($response, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}

class TinyDrive extends Buyers
{
    public $starred = array();

    public function __construct()
    {
        global $request;

        if(!$this->sessions->admin)
            return false;

        $action = $this->request->get('action', 'string');
        $request = json_decode($this->request->post());

        if($s = $this->request->cookie('starred'))
        {
            $this->starred = json_decode($s, true);
        }
        else
            setcookie('starred', json_encode($this->starred));

        if(method_exists($this,$action))
            call_user_func_array(array($this, $action), array());
    }

    private function list()
    {
        global $request;

        $folders = array();
        $images = array();
        $path = $request->parent ?? UPLOAD_DIR;

        $files = array_diff(scandir($path), array('..', '.'));
        foreach($files AS $file)
        {
            $filepath = $path . $file;

            if(!is_dir($filepath))
            {
                $item = $this->fileinfo($filepath);
                $images[] = $item;
            }
            else
            {
                $item = $this->dirinfo($filepath);
                $folders[] = $item;
            }
        }

        $res = new stdClass();
        $res->last = true;
        $res->files = array_merge($folders, $images);
        $res->offset = count($res->files);

        exit_json($res);
    }

    private function addfile()
    {
        $res = new stdClass();

        if(!$upload_dir = $this->request->get('subdir'))
            $upload_dir = UPLOAD_DIR;

        //при изменении фотки передаётся имя файла через ГЕТ параметр
        $name = $this->request->get('name');
        if($tmp = $this->request->files('file'))
        {
            $tmpfile = $tmp['tmp_name'];

            if(empty($name))
                $name = $tmp['name'];

            if(!$content = file_get_contents($tmpfile))
                exit_json(null);

            if(!$is_allowed_file = $this->allowed_file($content))
                exit_json(null);

            file_put_contents($upload_dir . $name, $content);

            $file = new stdClass();
            $res->file = $this->fileinfo($upload_dir . $name);
        }
        exit_json($res);
    }

    public function allowed_file($content)
    {
        //получаем первые 3 байта
        $header = substr($content, 0, 3);
        //берем 16-ти ричное значение прочитанных данных
        $check = unpack('H*', $header);
        $hex = strtolower($check[1]);
        return ALLOWED[$hex] ?? null;
    }

    private function commit()
    {
        global $request;

        $id = $request->id;
        $type = $request->type;

        $res = new stdClass();
        $res->file = $this->fileinfo($id);
        exit_json($res);
    }

    private function stars()
    {
        global $request;

        $images = array();
        foreach($this->starred AS $filepath)
            $images[] = $this->fileinfo($filepath);

        $res = new stdClass();
        $res->last = true;
        $res->files = $images;
        $res->offset = count($res->files);

        exit_json($res);
    }

    private function star()
    {
        global $request;

        foreach($request->ids AS $id)
        {
            if(!in_array($id, $this->starred))
                $this->starred[$id] = $id;
        }
        setcookie('starred', json_encode($this->starred));

        exit_json($request);
    }

    private function unstar()
    {
        global $request;

        foreach($request->ids AS $id)
            unset($this->starred[$id]);

        setcookie('starred', json_encode($this->starred));

        exit_json($request);
    }

    private function create()
    {
        global $request;

        $action_url = '/admin/ajax/tinydrive.php?';
        $url = array('action'=>'addfile', 'subdir'=>$request->parent ?? null, 'name'=>$request->name);

        $item = new stdClass();
        $item->name = "content-type";
        $item->value = "image/jpeg";

        $res = new stdClass();
        $res->id = !empty($request->parent) ? $request->parent.$request->name : UPLOAD_DIR.$request->name;
        $res->uploadUrl = $action_url . http_build_query($url);
        $res->blobUrl = $this->config->root_url.'/'.$res->id;
        $res->formItems = array($item);

        exit_json($res);
    }

    private function getMeta()
    {
        global $request;
        $res = new stdClass();
        $res->id = $request->id;
        $res->description = '';
        $res->createdBy = CREATED_BY;
        exit_json($res);
    }

    private function setMeta()
    {
        global $request;
        exit_json($request);
    }

    private function move()
    {
        global $request;

        foreach($request->ids AS $filepath)
        {
            $basename = pathinfo($filepath, PATHINFO_BASENAME);
            rename($filepath, $request->parent.$basename);
        }

        exit_json($request);
    }

    private function mkdir()
    {
        global $request;

        $dir = $request->parent ?? UPLOAD_DIR;
        mkdir($dir.$request->name);

        $res = new stdClass();
        $res->file = $this->dirinfo($dir.$request->name);

        exit_json($res);
    }

    private function rename()
    {
        global $request;

        $dir = pathinfo($request->id,  PATHINFO_DIRNAME).'/';
        rename($request->id, $dir.$request->name);

        //если переименовали избранный файл
        if(isset($this->starred[$request->id]))
        {
            //удалим предыдущий файл
            unset($this->starred[$request->id]);
            //добавим новый
            $this->starred[$dir.$request->name] = $dir.$request->name;
            //сохраним
            setcookie('starred', json_encode($this->starred));
        }

        $res = new stdClass();
        $res->file = $this->fileinfo($dir.$request->name);
        exit_json($res);
    }

    private function copy()
    {
        global $request;

        $basename = pathinfo($request->id, PATHINFO_BASENAME);
        copy($request->id, $request->parent . $basename);

        exit_json($request);
    }

    private function delete()
    {
        global $request;

        foreach($request->ids AS $url)
        {
            if(is_dir($url))
                delTree($url);
            else
                unlink($url);
        }

        exit_json($request);
    }


    private function dirinfo($filepath)
    {
        $item = new stdClass();
        $item->id = $filepath.'/';
        $item->url = null;
        $item->type = "directory";
        $item->thumbs = [];
        $item->starred = false;
        $item->size = 0;

        $item->name = pathinfo($filepath, PATHINFO_BASENAME);
        $item->path = "/".$item->name;
        $item->mdate = date("Y-m-d\TH:i:s\Z", filemtime($item->id));
        return $item;
    }

    private function fileinfo($filepath)
    {
        $extension = strtolower(pathinfo($filepath, PATHINFO_EXTENSION));

        $file = new stdClass();
        $file->id = $filepath;
        $file->url = $filepath;
        $file->type = "document";
        $file->thumbs = [];
        if($extension == 'jpg' || $extension == 'png' || $extension == 'gif')
        {
            $file->type = "image";
            $file->thumbs = ['512x512'];
        }
        $file->starred = isset($this->starred[$file->id]) ? true : false;
        $file->size = filesize($filepath);

        $file->name = pathinfo($filepath, PATHINFO_BASENAME);
        $file->path = $filepath;
        $file->mdate = date("Y-m-d\TH:i:s\Z", filemtime($file->id));

        return $file;
    }
}
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header("Content-type: application/json; charset=utf-8");

new TinyDrive();
?>
