Google Drive PHP API - Simple File Upload

I was able to run a PHP added in CRON. He asks for the verification code only the first time and then everything works. I've been running CRON for over 16h and everything is working perfectly.

Well, considering you've done the steps:

  1. Create a Project on Google Cloud Platform;
  2. In Credentials, you already have the OAuth 2.0 Client ID;
  3. Downloaded credentials and renamed credentials.json;
  4. Used composer to download Google Drive libraries;

References in:

  • https://developers.google.com/drive/api/v3/quickstart/php
  • https://developers.google.com/drive/api/v3/reference/files/create
  • https://developers.google.com/drive/api/v3/manage-uploads

This code here is the "working" result of an upload to Google Drive in a specific subfolder. I hope it helps.

<?php

ini_set('memory_limit', '4096M');

require __DIR__ . '/vendor/autoload.php';

function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName('Google Drive API PHP Quickstart');
    $client->setScopes(Google_Service_Drive::DRIVE);
    $client->setAuthConfig('credentials.json');
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');


    // Load previously authorized token from a file, if it exists.
    // The file token.json stores the user's access and refresh tokens, and is
    // created automatically when the authorization flow completes for the first
    // time.
    $tokenPath = 'token.json';
    if (file_exists($tokenPath)) {
        $accessToken = json_decode(file_get_contents($tokenPath), true);
        $client->setAccessToken($accessToken);
    }

    // If there is no previous token or it's expired.
    if ($client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($client->getRefreshToken()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        } else {
            // Request authorization from the user.
            $authUrl = $client->createAuthUrl();
            printf("Open the following link in your browser:\n%s\n", $authUrl);
            print 'Enter verification code: ';
            $authCode = trim(fgets(STDIN));

            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            $client->setAccessToken($accessToken);

            // Check to see if there was an error.
            if (array_key_exists('error', $accessToken)) {
                throw new Exception(join(', ', $accessToken));
            }
        }
        // Save the token to a file.
        if (!file_exists(dirname($tokenPath))) {
            mkdir(dirname($tokenPath), 0700, true);
        }
        file_put_contents($tokenPath, json_encode($client->getAccessToken()));
    }
    return $client;
}


// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);

// Print the names and IDs for up to 10 files.
// Esse resultado é importante para ver que tudo está concetado;
// Esse comando deve exibir as ultimas 3 atividades do seu drive;
$optParams = array(
  'pageSize' => 3,
  'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);

if (count($results->getFiles()) == 0) {
    print "No files found.\n";
} else {
    print "Files:\n";
    foreach ($results->getFiles() as $file) {
        printf("%s (%s)\n", $file->getName(), $file->getId());
    }
}
//
// Fim atividades do Drive;
//


//Define variáveis de arquivos
//Aqui você pode substituir depois par algum array ou resultado do banco de dados
//Defina um bem simples inicialmente para ver que tudo funciona
$pasta      = 'substitua pela pasta';   // Um exemplo aqui é /home/usuario/public_html/arquivos_upload
$arquivo    = 'substitua pelo arquivo'; // arquivo.mp4
    printf("Pasta: %s || Arquivo: %s\n", $pasta, $arquivo);
}

//Essa é a pasta destino do Google Drive
$parentId   = 'substitua pelo ID da Pasta';


if ( !empty($arquivo) ) {

    //Define localização da pasta e arquivo
    $file_path = $pasta.'/'.$arquivo;

    //Conecta no Drive da sua conta
    $file = new Google_Service_Drive_DriveFile();

    //Define nome do arquivo
    $file->setName($arquivo);

    //Define Diretório Destino lá no Google Drive
    $file->setParents(array($parentId));

    //Cria o arquivo no GDrive
    $service->files->create(
      $file,
      array(
        'data'          => file_get_contents($file_path),
        'mimeType'      => 'application/octet-stream',
        'uploadType' => 'resumable'
      )
    );

    // Grava Log do que foi feito UTC -3 horas;
    $DateTime = new DateTime();
    $DateTime->modify('-3 hours');
    $now = $DateTime->format("Y-m-d H:i:s");
    $logfile = $now.' Upload OK :: '.$arquivo.PHP_EOL;

    $myfile = file_put_contents('logs.txt', $logfile, FILE_APPEND | LOCK_EX);

} else {

    //Grava Log
    $now = date("Y-m-d H:i:s");
    $logfile .=$now.' =====SEM ARQUIVOS========'.PHP_EOL;

    $myfile = file_put_contents('logs.txt', $logfile, FILE_APPEND | LOCK_EX);

}

?>

Use this

<?php
    require_once 'google-api-php-client/src/Google_Client.php';
    require_once 'google-api-php-client/src/contrib/Google_DriveService.php';

    $client = new Google_Client();
    // Get your credentials from the console
    $client->setClientId('YOUR_CLIENT_ID');
    $client->setClientSecret('YOUR_CLIENT_SECRET');
    $client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
    $client->setScopes(array('https://www.googleapis.com/auth/drive'));

    $service = new Google_DriveService($client);

    $authUrl = $client->createAuthUrl();

    //Request authorization
    print "Please visit:\n$authUrl\n\n";
    print "Please enter the auth code:\n";
    $authCode = trim(fgets(STDIN));

    // Exchange authorization code for access token
    $accessToken = $client->authenticate($authCode);
    $client->setAccessToken($accessToken);

    //Insert a file
    $file = new Google_DriveFile();
    $localfile = 'a.jpg';
    $title = basename($localfile);
    $file->setTitle($title);
    $file->setDescription('My File');
    $file->setMimeType('image/jpeg');

    $data = file_get_contents($localfile);

    $createdFile = $service->files->insert($file, array(
          'data' => $data,
          'mimeType' => 'image/jpeg',
        ));

    print_r($createdFile);
    ?>

Use this code to authenticate and upload a test file. You need to set <YOUR_REGISTERED_REDIRECT_URI> (and also in console) to this document itself to authenticate.

require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';

$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('<YOUR_CLIENT_ID>');
$client->setClientSecret('<YOUR_CLIENT_SECRET>');
$client->setRedirectUri('<YOUR_REGISTERED_REDIRECT_URI>');
$client->setScopes(array('https://www.googleapis.com/auth/drive.file'));

session_start();

if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
    if (isset($_GET['code'])) {
        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
    } else
        $client->setAccessToken($_SESSION['access_token']);

    $service = new Google_Service_Drive($client);

    //Insert a file
    $file = new Google_Service_Drive_DriveFile();
    $file->setName(uniqid().'.jpg');
    $file->setDescription('A test document');
    $file->setMimeType('image/jpeg');

    $data = file_get_contents('a.jpg');

    $createdFile = $service->files->create($file, array(
          'data' => $data,
          'mimeType' => 'image/jpeg',
          'uploadType' => 'multipart'
        ));

    print_r($createdFile);

} else {
    $authUrl = $client->createAuthUrl();
    header('Location: ' . $authUrl);
    exit();
}