viernes, 4 de diciembre de 2015

22 - Tutorial de Laravel 5 - Download Files (Descargar archivos del servidor)




En este capítulo del Tutorial de Laravel 5 veremos un nuevo supuesto, en el cual nos solicitan incluir una opción en el Panel de Usuario para descargar un archivo pdf con los "términos y condiciones de uso del portal". La descarga de archivos sólo estará permitida a los usuarios autenticados.

Lo primero que haremos es agregar esta nueva opción a la vista "user.blade.php" ...

<li><a href="{{url('user/download')}}">Descargar términos y condiciones de uso</a></li>


A continuación crearemos la carpeta donde se incluirán los archivos descargables, si creamos esta carpeta en la carpeta "public" cometemos el error de que estará disponible a cualquier usuario, así que la crearemos en la carpeta "app" con el nombre "files" y le agregaremos un archivo pdf con el nombre "terminos.pdf".

A continuación agregaremos la ruta de descarga en routes.php, lógicamente es la misma que estamos indicando en el link de la opción ...

Route::get('user/download', 'UserController@download');


Esta ruta está conectada al controlador "UserController" y a una acción llamada "download", recuerden que sólo los usuarios autenticados pueden tener acceso a las acciones de este controlador.

Para la reutilización de código crearemos un nuevo método protegido llamado downloadFile, sólo accesible desde la clase y clases heredadas, este método lo podremos migrar a otra clase en caso de ser necesario. A este método tenemos que pasar un argumento, el cual es la ruta del archivo, este método regresa un valor boolean, si el archivo existe se procede a su descarga y retorna true, de lo contrario false. En el controlador UserController agregaremos el método ...

    protected function downloadFile($src){
        if(is_file($src)){
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $content_type = finfo_file($finfo, $src);
            finfo_close($finfo);
            $file_name = basename($src).PHP_EOL;
            $size = filesize($src);
            header("Content-Type: $content_type");
            header("Content-Disposition: attachment; filename=$file_name");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: $size");
            readfile($src);
            return true;
        } else{
            return false;
        }
    }


También en el controlador UserController agregaremos la acción "download", en esta acción haremos uso del método downloadFile comprobando si la descarga se ha realizado con éxito o no, si no es así, redireccionamos atrás nuevamente ...

    public function download(){
        if(!$this->downloadFile(app_path()."/files/terminos.pdf")){
            return redirect()->back();
        }
    }


Finalmente probaremos en el Panel de Control de usuario esta nueva opción.