<?php
    /**
    *
    * copyright (c) 2015-2019 Heliac Technologies
    * license http://opensource.org/licenses/gpl-license.php GNU GPL v3 
    *
    * Classe per gestire gli upload
    * 
    * $nomeFile
    * $tipiFileAmmessi
    * $dimensiomeMassima
    */

    class GestoreUpload {
        private $percorsoBaseDownload;
        private $sottoCartelle;
        private $ultimaCartellaCreata;
        private $limiteFileCartella;
        private $prefissoCartella;
        private $prefissoFile;
        private $tipiFileAmmessi;
        private $dimensioneMassima;
        private $file;

        public function __construct($nomeFile,$tipiFileAmmessi,$dimensiomeMassima,$percorsoBaseDownload,$limiteFileCartella,$prefissoFile="",$prefissoCartella="") {
            if($nomeFile!="") {
                $this->file = $_FILES[$nomeFile];
            }
            $this->tipiFileAmmessi = $tipiFileAmmessi;
            $this->percorsoBaseDownload = $percorsoBaseDownload;
            $this->limiteFileCartella = $limiteFileCartella;
            $this->dimensioneMassima  = $dimensiomeMassima;
            $this->prefissoCartella   = $prefissoCartella;
            $this->prefissoFile       = $prefissoFile;
            
            /*
             * se il limite dei file per cartella calcola le sottocartelle, altrimenti questi calcoli 
             * non sono necessari e le variabili sottocartelle e ultimaCartellaCreata vengono inizializzate
             * con una stringa vuota
             */
            if($this->limiteFileCartella>0) {
                $dataTmp = 0;
                $this->sottoCartelle = glob($percorsoBaseDownload."/*", GLOB_ONLYDIR);
                foreach($this->sottoCartelle as $sottoCartella) {
                    if(filectime($sottoCartella)>$dataTmp) {
                        $dataTmp = filectime($sottoCartella);
                        $this->ultimaCartellaCreata =$sottoCartella;					
                    }
                }
            }
        }

        /*
         * metodo che salva il o i file passati in input sul server
         * controlla se si tratta di un solo file o se ne sono di più,
         * poi chiama il metodo appropriato
         */
        public function salvaFile($nome = "") {
            if($this->file['tmp_name']=="") {
                $risultato["percorso"] = "";
                $risultato["errore"]   = "Nessun file caricato";
            }
            else if(is_array($this->file['name']) && count($this->file['name'])==1) {
                $this->normalizzaFileInput();
                return $risultato["percorso"] = $this->salvaSingoloFile($nome);
            }
            else if(is_string($this->file['name'])) {
                return $risultato["percorso"] = $this->salvaSingoloFile($nome);
            }
            else {
                return $this->salvaPiuFile($nome);
            }
        }
        
        /*
         * metodo che salva un singolo file sul server
         * prima di salvare controlla che il file sia delle estensioni accettate
         * e che abbia una dimensione inferiore a quella massima, in caso contrario
         * da errore
         * 
         * Se il parametro $nome non viene inserito verrà usato il nome del file
         */
        public function salvaSingoloFile($nome) {
            $risultato = array();
            $risultato["percorso"] = "";
            $risultato["errore"]   = "";
            $risultato["fileElaborati"] = 1;
            $mimetype = mime_content_type($this->file['tmp_name']);

            if(!in_array($mimetype, $this->tipiFileAmmessi)) {
                $risultato["errore"] = "Il tipo di file $mimetype non è ammesso";
            }
            
            if($this->file['size']/1000000 > $this->dimensioneMassima) {
                $risultato["errore"] = "Il file eccede la dimensione massima";
            }
            
            if($nome == "") { // se il nome non è stato inserito viene usato il nome del file
                $nomeFile = $this->creaNomeFile($this->file['name']);
            }
            else { // altrimenti si usa il nome passato in input
                $nomeFile = $this->creaNomeFile($nome);
            }
            
            // se è stato impostato un limite di file per cartella viene elaborato il 
            // percorso con il metodo percorsoNuovoFile, altrimenti impostato come
            // percorso file la variabile percorsoBaseDownload
            if($this->limiteFileCartella>0) {
                $percorsoFile = $this->percorsoNuovoFile($nomeFile);
            }
            else {
                $percorsoFile = $this->percorsoBaseDownload."/".$nomeFile;
            }
            
            if($risultato["errore"]=="") {      
                move_uploaded_file($this->file['tmp_name'], $percorsoFile);
                $risultato["percorso"] = $percorsoFile;
            }
            return $risultato;
        }
        
        /*
         * metodo che salva più file sul server
         * con un ciclo controlla che ogni file sia delle estensioni accettate
         * e che abbia una dimensione inferiore a quella massima, in caso contrario
         * da errore
         * 
         * Se il parametro $nome non viene inserito verrà usato il nome di ogni file,
         * altrimenti verrà usato il parametro 
         */
        public function salvaPiuFile($nome) {
            $arrayRisultati = array();
            $fileElaborati = 0;
            $elencoRisultati = array();
            foreach($this->file['tmp_name'] as $key=>$value) {
                $fileElaborati ++;
                $risultato = array();
                $risultato["percorso"] = "";
                $risultato["errore"]   = "";
                $mimetype = mime_content_type($this->file['tmp_name'][$key]);
                
                if(!in_array($mimetype, $this->tipiFileAmmessi)) {
                    $risultato["errore"] = "Questo tipo di file non è ammesso";
                }

                if($this->file['size'][$key]/1000000 > $this->dimensioneMassima) {
                    $risultato["errore"] = "Il file eccede la dimensione massima";
                }

                if($nome == "" && $value != "") { // se il nome non è stato inserito viene usato il nome del file
                    $nomeFile = $this->creaNomeFile($this->file['name'][$key]);
                }
                else { // altrimenti si usa il nome passato in input
                    $nomeFile = $this->creaNomeFile($nome);
                }

                // se è stato impostato un limite di file per cartella viene elaborato il 
                // percorso con il metodo percorsoNuovoFile, altrimenti impostato come
                // percorso file la variabile percorsoBaseDownload
                if($this->limiteFileCartella>0) {
                    $percorsoFile = $this->percorsoNuovoFile($nomeFile);
                }
                else {
                    $percorsoFile = $this->percorsoBaseDownload."/".$nomeFile;
                }

                if($risultato["errore"]=="") {
                    move_uploaded_file($this->file['tmp_name'][$key], $percorsoFile);
                    $risultato["percorso"] = $percorsoFile;
                }
                $elencoRisultati[count($elencoRisultati)] = $risultato;
            }
            $arrayRisultati["fileElaborati"] = $fileElaborati;
            $arrayRisultati["elencoRisultati"] = $elencoRisultati;
            return $arrayRisultati;
        }
        
        /*
         * Metodo che restituisce il nome che deve avere il file, 
         */
        public function creaNomeFile($nome) {
            $infoFile = pathinfo($nome);
            $nomeProvvisorio = str_replace(" ", "-", $infoFile["filename"]);
            $nuovoNome = preg_replace( '/[^a-z0-9_-]/i', '',$this->prefissoFile.$nomeProvvisorio);
            return $nuovoNome.".".$infoFile['extension'];
        }
        
        public function percorsoNuovoFile($nome,$rinominaFile) {
            $numeroFile = count(scandir($this->ultimaCartellaCreata));
            if($numeroFile < $this->limiteFileCartella) {
                if($rinominaFile) {
                    $uniqid = uniqid("");
                    return $this->ultimaCartellaCreata."/".$uniqid.$nome;
                }
                else {
                    return $this->ultimaCartellaCreata."/".$nome;
                }
            }
            else {
                $nome = $this->prefissoCartella.date("Ymd");
                $this->creaSottoCartella($nome);
                $this->ultimaCartellaCreata = $nome;
                if($rinominaFile) {
                    $uniqid = uniqid("");
                    return $this->ultimaCartellaCreata."/".$uniqid.$nome;
                }
                else {
                    return $this->ultimaCartellaCreata."/".$nome;
                }
            }
        }
        
        /*
         * può capitare che ci sia un solo elemento, ma sia un array che 
         * a sua volta contiene array. In questo caso va normalizzato
         */
        public function normalizzaFileInput() {
            $this->file['tmp_name'] = $this->file['tmp_name'][0];
            $this->file['name'] = $this->file['name'][0];
            $this->file['size'] = $this->file['size'][0];
        }
        
        public function creaSottoCartella($nome) {
            mkdir($this->percorsoBaseDownload."/$nome".directory, 755, true);
        }

        public function fileCartella($nome) {
            return scandir($this->percorsoBaseDownload."/$nome");
        }


        public function getUltimaCartellaCreata() {
            return $this->ultimaCartellaCreata;
        }
    }