¿cómo subir archivos desde mi web a la nube?

publicado por: Anonymous

tengo un “sistema” que permite subir y descargar archivos en el propio servidor ¿inconvenientes? que no se puede editar en el navegador, únicamente aquellos archivos que son del tipo “Imagen” permiso visualizarlos, y los que no, simplemente cuando intentan visualizarlo fuerzo la descarga, es algo totalmente obsoleto.

Quiero que mi “sistema” permita subir, editar, imprimir y descargar archivos; por lo tanto pensé en implementar la API de Google Drive, no sé como funciona, ayer perdí todo el día y no pude hacerlo funcionar.

A mi me gustaría lo siguiente: que google drive me proporcione un código javascript que yo ponga en formulario de subida de archivos y que automáticamente lo suba a la cuenta propia del sistema y que me retorne la URL para que yo pueda almacenarla en BD. Posteriormente cuando alguien quiera visualizar, editar, imprimir o descargar ese archivo yo simplemente con la URL delego todo ese trabajo a la API.

Copié un código de internet y me solicitó iniciar sesión, la verdad estoy super confuso de como hacerlo funcionar. Para aclarar, yo no quiero que los archivos se suban a las cuentas personales de los usuarios, quiero que se suban automáticamente a una cuenta que voy a crear sólo y exclusivamente para ser usada en el servidor.

¿Podrían por favor ayudarme? Uso PHP

Onedrive SDK

solución

Referencia de Google Drive API: https://developers.google.com/drive/api/v3/about-sdk
Referencia de como usar la librería de PHP: https://developers.google.com/api-client-library/php/start/get_started

Aquí te dejo un ejemplo de un gestor de archivos usando Google Drive

Requisitos:

1. Un servidor local para operar con PHP y MySQL (WAMP, MAMP, Etc)
2. Una cuenta de google
3. Un navegador (Google chrome de preferencia)

Paso #1 (Preparando el directorio y la librería)

1. Creemos un directorio raíz y elijamos el nombre que más nos guste.
2. Descargamos a este directorio la librería de APIs de Google y la descomprimimos.
3. Creemos otra carpeta donde vamos a tener nuestros archivos con código, y a ésta la nombramos “gestor“. De modo que tiene que mirarse similar a esto:

introducir la descripción de la imagen aquí

Paso #2 (Preparando los archivos de código)

1. Dentro del directorio “gestor”, creamos los siguientes archivos:

  • acceso.php
  • autenticar.php
  • descargar.php
  • gestor.html
  • index.php
  • listar.php
  • script.js
  • subir.php

De modo que la lista de archivos se tiene que ver similar a esto:
introducir la descripción de la imagen aquí

Paso #3 (Llenando los archivos de código su código respectivo)

1. Dentro del archivo acceso.php, ponemos el siguiente código:

<?php

session_start();

//incluir la liberería de php de Google API
require_once '../google-api-php-client-2.1.3/vendor/autoload.php';

//deifnir los permisos requeridos
$scopes = array('https://www.googleapis.com/auth/drive');

//crear el objeto cliente
$cliente = new Google_Client(); 
$cliente->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/gestor/acceso.php');
$cliente->setAuthConfig("client_secret.json");
$cliente->addScope($scopes);
$cliente->setAccessType('offline');

if (isset($_SESSION['token_de_acceso']) && $_SESSION['token_de_acceso']) {  

  $servidor = "localhost";
  $usuario = "root";
  $contraseña = "";

  //crear conexión
  $con = new mysqli($servidor, $usuario, $contraseña);

  //revisar la conexión
  if ($con->connect_error) {
    die("Fallo en la conexión: " . $con->connect_error);
  } 

  //crear base de datos si no existe
  $sql = "CREATE DATABASE IF NOT EXISTS gestor";
  if ($con->query($sql) === TRUE) {
      echo "Base de datos creada con éxito<br><br>";
  } else {
      echo "Fallo creando base de datos: " . $con->error . "<br><br>";
  }

  mysqli_select_db($con,"gestor");

  //crear tabla en la base de datos si no existe
  $sql = "CREATE TABLE IF NOT EXISTS token (id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, token_de_acceso VARCHAR(2000))";
  if ($con->query($sql) === TRUE) {
      echo "Tabla creada con éxito<br><br>";
  } else {
      echo "Fallo creando la tabla: " . $con->error . "<br><br>";
  }

  //guardar el token de acceso en forma de un JSON string
  $token_de_acceso = json_encode($_SESSION['token_de_acceso']);
  $sql = "INSERT INTO token (token_de_acceso) VALUES ('$token_de_acceso')";
  if ($con->query($sql) === TRUE) {
    echo "Token guardado con éxito<br><br>";
  } else {
      echo "Error guardado token: " . $sql . "<br>" . $con->error . "<br><br>";
  }

  $con->close();
  header("Location: index.php");

} else {

  if (!isset($_GET['code'])) {

    $url_de_auth = $cliente->createAuthUrl();
    header('Location: ' . filter_var($url_de_auth, FILTER_SANITIZE_URL));

  } else {

    $cliente->authenticate($_GET['code']);
    $_SESSION['token_de_acceso'] = $cliente->getAccessToken();
    $uri_de_redireccion = 'http://' . $_SERVER['HTTP_HOST'] . '/gestor/acceso.php';
    header('Location: ' . filter_var($uri_de_redireccion, FILTER_SANITIZE_URL));

  }

}

2. Dentro del archivo autenticar.php ponemos el siguiente código:

<?php session_start(); 

function inicarCliente(){

    //incluir la liberería de php de Google API
    require_once "../google-api-php-client-2.1.3/vendor/autoload.php"; 

    //definir los permisos necesarios 
    $scopes = array("https://www.googleapis.com/auth/drive");

    //crear el objeto de cliente de Google
    $cliente = new Google_Client(); 
    $cliente->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/gestor/acceso.php');
    $cliente->setAuthConfig("client_secret.json");
    $cliente->addScope($scopes);
    $cliente->setAccessType('offline');

    return $cliente;

}

function refrescarToken($cliente, $tokenDeAccesso){

    $tokenExpirado = $cliente->isAccessTokenExpired();
    if($tokenExpirado){
        $cliente->refreshToken($tokenDeAccesso["refresh_token"]);
    }

    $_SESSION["token_de_acceso"] = $cliente->getAccessToken(); 
}

?>

3. Dentro del archivo descargar.php ponemos el siguiente código:

<?php

include "autenticar.php";

$idDeDoc = $_POST["idDeDoc"];
$tituloDeDoc = $_POST["tituloDeDoc"];
$tipoDeDoc = $_POST["tipoDeDoc"];

function descargarArchivo($idDeDoc, $tipoDeDoc, $tituloDeDoc){

    $tokenDeAccesso = $_SESSION["token_de_acceso"];

    $cliente = inicarCliente();
    refrescarToken($cliente, $tokenDeAccesso);

    $tokenDeAccesso = $_SESSION['token_de_acceso'];

    $cliente->setAccessToken($tokenDeAccesso);
    $servicio = new Google_Service_Drive($cliente);

    if($tipoDeDoc == "application/vnd.google-apps.document") {

        $ext = ".docx";
        $format = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        $googleDoc = true;

    } else if($tipoDeDoc == "application/vnd.google-apps.spreadsheet"){

        $ext = ".xlsx";
        $format = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        $googleDoc = true;

    } else if($tipoDeDoc == "application/vnd.google-apps.presentation"){

        $ext = ".pptx";
        $format = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        $googleDoc = true;

    } else {

        $ext = ".".explode("/", $tipoDeDoc)[1];
        $googleDoc = false;

    }

    if($googleDoc){
        $archivo = $servicio->files->export($idDeDoc, $format, array('alt' => 'media'));
    } else {
        $archivo = $servicio->files->get($idDeDoc, array('alt' => 'media'));
    }

    $exportacion = fopen($tituloDeDoc.$ext, "w+");
    fwrite($exportacion, $archivo->getBody());
    fclose($exportacion);

    return dirname($tituloDeDoc.$ext)."/".$tituloDeDoc.$ext;
}

echo descargarArchivo($idDeDoc, $tipoDeDoc, $tituloDeDoc);

?>

4. Dentro del archivo gestor.html ponemos el siguiente código:

<!DOCTYPE html>
<html>
<head>
    <title>Gestor Drive</title>
    <style type="text/css">

        body{
            text-align: center;
        }

        .listaArchivos {
            margin: 15px 0px;
            width: 320px;
            height: 25px;
        }

        #descargar{
            margin: 7px 0px;
        }

        #editarArchvio{
            width: 950px;
            height: 630px;
        }

        #circuloEspera,
        #circuloEsperaDos {
            display: none;
            height: 36px;
            width: 36px;
            margin: 0 auto;
        }

        #subirArchivo {
            margin: 35px 0px;
        }

        #popup {
            position: absolute;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
            top: 0;
            left: 0;
            display: none;
        }

        #contenido-popup {
            background-color: white;
            width: 450px;
            height: 240px;
            margin: 0 auto;
            transform: translateY(100%);
            position: relative;
        }

        .btn {
            padding: 6px;
            border-radius: 3px;
            background-color: whitesmoke;
            box-shadow: 0px 0px 1px 1px gray;
        }

        #nombreDeArchivo{
            height: 20px;
        }

    </style>
</head>
<body>

    <h1>Gestor de Archivos Google Drive</h1>

    <div class="menu">

        <select class="listaArchivos" id="listaDeArchivos" disabled>
            <option>Seleccionar archivo...</option>         
        </select>

        <br>

        <button id="descargar" disabled>Descargar</button>
        <img id="circuloEspera" src="https://s5.postimg.cc/r3dog8vg7/loading.gif">

    </div>

    <div class="marco">

        <iframe src="" id="editarArchvio" frameborder="1"></iframe>

    </div>

    <button id="subirArchivo">Subir Archivo</button>

    <div id="popup">
        <div id="contenido-popup">
            <br>
            <h3>SUBIR NUEVO ARCHIVO</h3>
            <br>
            <label for="nuevoArchivoInput" class="btn">Seleccionar Archivo</label><br>
            <input type="file" name="archivo" id="nuevoArchivoInput" style="visibility:hidden;"><br>
            <div id="nombreDeArchivo"></div><img id="circuloEsperaDos" src="https://s5.postimg.cc/r3dog8vg7/loading.gif"><br><br>
            <button id="nuevoArchivo">Subir Nuevo Archivo</button>
        </div>
    </div>

<script type="text/javascript" src="scripts.js"></script>
</body>
</html>

5. Dentro del archivo index.php ponemos el siguiente código:

<?php

    session_start();

    $servidor = "localhost";
    $usuario = "root";
    $contraseña = "";
    $baseDeDatos = "gestor";

    //crear conexión
    $con = new mysqli($servidor, $usuario, $contraseña, $baseDeDatos);

    //revisar la conexión
    if ($con->connect_error) {
        if($con->connect_error == "Unknown database 'gestor'") {
            header("Location: acceso.php");
        } 
        die("Fallo en la conexión: " . $con->connect_error);
    } 

    //obtener token de accesso
    $sql = "SELECT * FROM token";
    $result = $con->query($sql);

    if ($result->num_rows > 0) {
        // obtener datos de cada fila
        while($row = $result->fetch_assoc()) {
            $token = $row["token_de_acceso"];
            break;
        }
    } else {
        echo "0 resultados";
        header("Location: acceso.php");
    }

    //cerrar conexión
    $con->close();

    //guardar el token de acceso en la sesión y redirigir a gestor.html
    $_SESSION["token_de_acceso"] = json_decode($token, true);
    header("Location: gestor.html");

?>

6. Dentro del archivo listar.php ponemos el siguiente código:

<?php

include "autenticar.php";

function obtenerListaDeArchivos(){

    $tokenDeAccesso = $_SESSION["token_de_acceso"];

    $cliente = inicarCliente();
    refrescarToken($cliente, $tokenDeAccesso);

    $tokenDeAccesso = $_SESSION['token_de_acceso'];

    $opcionesDeHtml = "<option value=''>Seleccionar archivo...</option>";

    $cliente->setAccessToken($tokenDeAccesso);
    $servicio = new Google_Service_Drive($cliente);

    $tokenDePagina = null;
    $paramsOpcionales = array(
        "pageSize" => 100,
        "pageToken" => $tokenDePagina,
        "q" => "'Id de folder aqui' in parents and trashed != true" // normalmente es algo como 1HeqmJX-1Lsy89CXljmUY-BjubbjfkpsSm
    );

    try {

        do {

            $optParams["pageToken"] = $tokenDePagina;
            $archivos = $servicio->files->listFiles($paramsOpcionales);
            $tokenDePagina = $archivos->nextPageToken;

            foreach ($archivos as $archivo ) {
                $opcionesDeHtml .= "<option value='".$archivo->id.",".$archivo->mimeType."'>".$archivo->name."</option>";
            }

        } while($tokenDePagina);

    } catch(Exception $e) {

        $msjDeError = $e->getMessage();

        if(strpos($msjDeError, "Internal Error") !== false) {
            sleep(2);
            $archivos = $servicio->files->listFiles($paramsOpcionales);
            $tokenDePagina = $driveFiles->nextPageToken;
            foreach ($drivefiles as $file ) {
                $opcionesDeHtml .= "<option value='".$archivo->id."'>".$archivo->name."</option>";
            }
        } else {
            print $msjDeError;
        }
    }

    return $opcionesDeHtml;

}

echo obtenerListaDeArchivos();

?>

OJO con este archivo. Favor de reemplazar “Id de folder aqui” con la Id del folder de google drive donde se van a guardar los archivos.

7. Dentro del archivo scripts.js ponemos el siguiente código:

function listarArchivos(){

  var solicitud = new XMLHttpRequest();
  solicitud.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("listaDeArchivos").innerHTML = this.responseText;
        document.getElementById("listaDeArchivos").disabled = false;
    }
  };
  solicitud.open("GET", "listar.php", true);
  solicitud.send();

}

function editarArchivo(){

    var elDoc = document.getElementById("listaDeArchivos").value;
    var idDeDoc = elDoc.split(",")[0];
    var tipoDeDoc = elDoc.split(",")[1];
    if(idDeDoc){
        document.getElementById("descargar").disabled = false;
    } else{
        document.getElementById("descargar").disabled = true;
    }

    var altura = (window.innerHeight / 3);
    altura = altura * 2;

    var url;
    if(tipoDeDoc === "application/vnd.google-apps.document"){

        url = "https://docs.google.com/document/d/"+idDeDoc+"?rm=demo";

    } else if(tipoDeDoc === "application/vnd.google-apps.spreadsheet"){

        url = "https://docs.google.com/spreadsheets/d/"+idDeDoc+"?rm=demo";

    } else if(tipoDeDoc === "application/vnd.google-apps.presentation"){

        url = "https://docs.google.com/presentation/d/"+idDeDoc+"?rm=demo";

    } else {

        url = "https://drive.google.com/file/d/"+idDeDoc+"/preview";

    }
    document.getElementById("editarArchvio").setAttribute("src", url);  
}

function descargarArchivo(){

    document.getElementById("descargar").style.display = "none";
    document.getElementById("circuloEspera").style.display = "initial";

    var elDoc = document.getElementById("listaDeArchivos").value;
    var idDeDoc = elDoc.split(",")[0];
    var tipoDeDoc = elDoc.split(",")[1];
    var tituloDeDoc = document.getElementById("listaDeArchivos").options[document.getElementById("listaDeArchivos").selectedIndex].text;

    var solicitud = new XMLHttpRequest();   
    solicitud.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {

            console.log(this.responseText);
            document.getElementById("descargar").style.display = "initial";
            document.getElementById("circuloEspera").style.display = "none";

            var a = document.createElement('a');
            a.href = this.responseText;
            a.download = (this.responseText).substr(2);
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        }
    };
    solicitud.open("POST", "descargar.php", true);
    solicitud.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    solicitud.send("idDeDoc="+idDeDoc+"&tipoDeDoc="+tipoDeDoc+"&tituloDeDoc="+tituloDeDoc);

}

function subirArchivo(){

    document.getElementById("nombreDeArchivo").style.display = "none";
    document.getElementById("circuloEsperaDos").style.display = "block";

    var elDoc = document.getElementById("nuevoArchivoInput");
    var path = elDoc.value.split("\"); 
    var tituloDeDoc = path[path.length -1];

    var formData = new FormData();
    formData.append("archivoParaSubir", elDoc.files[0]);
    formData.append("tituloDeDoc", tituloDeDoc);

    var solicitud = new XMLHttpRequest();   
    solicitud.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {

            console.log(this.responseText);
            document.getElementById("nombreDeArchivo").style.display = "block";
            document.getElementById("nombreDeArchivo").innerHTML = "Archvio subido";
            document.getElementById("circuloEsperaDos").style.display = "none";
            listarArchivos();
        }
    };
    solicitud.open("POST", "subir.php", true);
    solicitud.send(formData);
}

document.addEventListener("DOMContentLoaded", function(event) {

    listarArchivos();

    document.getElementById("listaDeArchivos").addEventListener("change", function(){
        editarArchivo();
    });

    document.getElementById("descargar").addEventListener("click", function(){
        descargarArchivo();
    });

    document.getElementById("subirArchivo").addEventListener("click", function(){
        document.getElementById("popup").style.display = "block";
    });

    document.getElementById("popup").addEventListener("click", function(e){
        if(e.target === document.getElementById("popup")){
            document.getElementById("popup").style.display = "none";
        }       
    });

    document.getElementById("nuevoArchivoInput").addEventListener("change", function(){
        var path = (this.value).split("\");
        document.getElementById("nombreDeArchivo").innerHTML = path[path.length - 1];
    });

    document.getElementById("nuevoArchivo").addEventListener("click", function(){
        subirArchivo();
    });

});

8. Dentro del archivo subir.php ponemos el siguiente código:

<?php

include "autenticar.php";

$archivoParaSubir = $_FILES["archivoParaSubir"];
$tituloDeDoc = $_POST["tituloDeDoc"];
$tituloDeDocPartes = explode(".", $tituloDeDoc);
array_pop($tituloDeDocPartes);
$tituloDeDoc = implode(".", $tituloDeDocPartes);


function subirArchivo($archivoParaSubir, $tituloDeDoc){

    $tokenDeAccesso = $_SESSION["token_de_acceso"];

    $cliente = inicarCliente();
    refrescarToken($cliente, $tokenDeAccesso);

    $tokenDeAccesso = $_SESSION['token_de_acceso'];

    $cliente->setAccessToken($tokenDeAccesso);
    $servicio = new Google_Service_Drive($cliente);

    $info = new finfo(FILEINFO_MIME);
    $tipoDeDoc = $info->file($archivoParaSubir["tmp_name"]);
    $mimeType = explode(";", $tipoDeDoc)[0];

    $metaDatos = new Google_Service_Drive_DriveFile(array('name' => $tituloDeDoc, "parents" => ["Id del folder de drive"])); // normalmente es algo así 1HeqmBX-1Lsy8dMAjmUY-Bjufvfsadf
    switch ($mimeType) {

        case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
        case "application/vnd.openxmlformats-officedocument.wordprocessingml.template":     
        case "application/vnd.ms-word.document.macroEnabled.12":
        case "application/vnd.ms-word.template.macroEnabled.12":
        case "application/msword":
            $metaDatos->setMimeType("application/vnd.google-apps.document");
            break;

        case "application/vnd.openxmlformats-officedocument.spreadsheetml.template":
        case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":   
        case "application/vnd.ms-excel.sheet.binary.macroEnabled.12":   
        case "application/vnd.ms-excel.template.macroEnabled.12":
        case "application/vnd.ms-excel.sheet.macroEnabled.12":
        case "application/vnd.ms-excel.addin.macroEnabled.12":
        case "application/vnd.ms-excel":
            $metaDatos->setMimeType("application/vnd.google-apps.spreadsheet");
            break;  

        case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
        case "application/vnd.openxmlformats-officedocument.presentationml.slideshow":  
        case "application/vnd.openxmlformats-officedocument.presentationml.template":   
        case "application/vnd.ms-powerpoint.presentation.macroEnabled.12":
        case "application/vnd.ms-powerpoint.slideshow.macroEnabled.12":
        case "application/vnd.ms-powerpoint.template.macroEnabled.12":
        case "application/vnd.ms-powerpoint.addin.macroEnabled.12":
        case "application/vnd.ms-powerpoint":
            $metaDatos->setMimeType("application/vnd.google-apps.presentation");
            break;  

        default:
            break;
    }

    $contenido = file_get_contents($archivoParaSubir["tmp_name"]);
    $archivo = $servicio->files->create($metaDatos, array(
        "data" => $contenido,
        "mimeType" => $mimeType,
        "uploadType" => "multipart",
        "fields" => "id")
    );

    $permiso = new Google_Service_Drive_Permission(array(
        'type' => 'anyone',
        'role' => 'writer',
    ));
    $compartir = $servicio->permissions->create(
        $archivo->id, $permiso, array('fields' => 'id'));

    return $archivo->id;
}

echo subirArchivo($archivoParaSubir, $tituloDeDoc);

?><br>

Ojo con este archivo, pues hay que reemplazar “Id del folder” con la id del folder donde vas a subir los archivos.

Paso #4 (Habilitando la API dentro de un proyecto y obtener el client secret)

1. Ir a la Consola de APIs y si no hemos creado un proyecto, crear uno.
2. Luego de crear el proyecto, habilitamos la API de Google Drive de la siguiente manera:

  • Abrimos el menú de la consola de desarrolladores y seleccionamos la opciones que nos detalla la imagen:
    introducir la descripción de la imagen aquí

  • Luego buscamos la API de Google drive y damos click:
    introducir la descripción de la imagen aquí

  • Después procedemos a habilitar la API dando click en el botón azul.
    introducir la descripción de la imagen aquí

  • A continuación, procedemos a ir a la sección de credenciales. Damos click en el menú y seleccionamos la opción detallada en la imagen:
    introducir la descripción de la imagen aquí

  • Después, establecemos el nombre de la app tal y como lo detalla la imagen:
    introducir la descripción de la imagen aquí

  • Ahora pasamos a la siguiente opción y seleccionamos el tipo de credencial que queremos crear, tal y como lo indica la imagen:
    introducir la descripción de la imagen aquí

    • Luego de seleccionar el tipo de credencial, escogemos para qué tipo de aplicación la vamos a usar. Seleccionamos la opción que nos indica la imagen y escribimos el valor que nos indica la imagen en la sección de “Authorized redirect URIs”:
      introducir la descripción de la imagen aquí

  • Luego de crear la credencial, nos va a salir una ventana con los valores de client secret y api key. Ignoramos eso. Y luego procedemos dar click en la flechita para descargar nuestro client secret.
    introducir la descripción de la imagen aquí

  • Por último, guardamos este archivo json en la carpeta “gestor”, dentro de nuestro directorio de trabajo; Es decir, donde están los otro archivos, y le ponemos el nombre de “client_secret.json“:
    introducir la descripción de la imagen aquí

¡ Listo ! Tenemos todo para hacer la prueba. Ahora simplemente ve a http://localhost/gestor y el resto sucederá por sí mismo. Los archivos con los que ya he probado son .pdf, .xlsx, pptx, .jpeg y .png.

Espero que esto te sirva de ayuda como una guía y si te es útil esto, no olvides de marcar la respuesta como aceptada.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *