<?php
    include_once "Reflection.php";
    class RequestFile
    {
        use ReflectionHook;
        public static $ready = false;
        public static $files = [];
        public function __construct()
        {
            if(!RequestFile::$ready)
            {
                RequestFile::$files = $this->files();
                RequestFile::$ready = true;
            };
        }
        public function getAttribute($name)
        {
            return $this->getFile($name);
        }
        public function hasFile($name)
        {
            return RequestFile::$files->{$name} ? $this->count($name) : false;
        }
        public function getFile($name)
        {
            return $this->hasFile($name) ? RequestFile::$files->{$name} : null;
        }
        public function count($name)
        {
            return count(RequestFile::$files->{$name});
        }
        public function save($field, $directory, $filename = false, $index = 0)
        {
            $file = $this->getFile($field)[$index];
            if($filename == false)
            {
                $filename = explode('.', $file->name);
                if(count($filename) == 1)
                {
                    $ext = ".bin";
                }
                else
                {
                    $ext = end($filename);
                };
                $filename = bin2hex(random_bytes(16)) . "." . $ext;
            }
            if(move_uploaded_file($file->tmp, $directory . "/" . $filename))
            {
                return $filename;
            }
            else
            {
                return false;
            }
        }
        public function saveAll($field, $directory, $filename = false, $max = -1)
        {
            $files = $this->getFile($field);
            $current = 0;
            foreach ($files as $file)
            {
                $file->save($directory, $filename);
                $current++;
                if($current == $max && $max != -1)
                {
                    break;
                }
            }
        }
        public function files()
        {
            $arg = new stdClass;
            foreach ($_FILES as $name => $file)
            {
                $arg->{$name} = [];
                for($i = 0; $i < count($file["name"]); $i++)
                {
                    $arg->{$name}[] = new UploadedFile(
                        $i,
                        $this,
                        $name,
                        $file["name"][$i],
                        $file["full_path"][$i],
                        $file["type"][$i],
                        $file["tmp_name"][$i],
                        $file["error"][$i],
                        $file["size"][$i]
                    );
                }
            };
            return $arg;
        }
    }
    class UploadedFile
    {
        public $name;
        public $path;
        public $mime;
        public $tmp;
        public $error;
        public $size;

        public $index;
        public $requestFile;
        public $field;
        public function __construct(
            $index,
            $requestFile,
            $field,
            $name,
            $path,
            $mime,
            $tmp,
            $error,
            $size
        )
        {
            $this->name = $name;
            $this->path = $path;
            $this->mime = $mime;
            $this->tmp = $tmp;
            $this->error = $error;
            $this->size = $size;
            $this->index = $index;
            $this->requestFile = $requestFile;
            $this->field = $field;
        }
        //save($field, $directory, $filename = false, $index = 0)
        public function save($directory, $filename = false)
        {
            $this->requestFile->save(
                $this->field,
                $directory,
                $filename,
                $this->index
            );
        }
        public function saveAll($directory, $filename = false, $max = -1)
        {
            $this->requestFile->saveAll(
                $this->field,
                $directory,
                $filename,
                $max
            );
        }
    }