10

I am having serious issues with the documentation for the new google drive API client library. It seems this should be an easy one to answer without having to put it on stackoverflow. I am seriously considering rolling my own on this one, a 64 page library that "just works" is so far a "total headache"

How the heck do you set the uploadType to "resumable" instead of the default "simple". I have searched the library for a way to do this, but it seems non-existent. Their only hint is the code on their sample uploader page https://developers.google.com/drive/quickstart-php

//Insert a file
$file = new Google_DriveFile();
$file->setTitle('My document');
$file->setDescription('A test document');
$file->setMimeType('text/plain');

$data = file_get_contents('document.txt');

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

Nothing here sets the uploadType...???

Their docs on another page just show uploadType as a part of the address as a GET: https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable but when you use $service->files->insert, the library sets the address.

Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
pathfinder
  • 1,606
  • 18
  • 22
  • 3
    all of these types of questions could be avoided if google just had a set of documentation similar to how jQuery documents their library. It would be awesome if they at least had a list of all the methods available in the php client library sorted by class somewhere online. Does something like that exist? – pathfinder Nov 18 '12 at 17:51

2 Answers2

6

The following sample will work with the latest version of the Google APIs PHP Client (https://code.google.com/p/google-api-php-client/source/checkout)

if ($client->getAccessToken()) {
  $filePath = "path/to/foo.txt";
  $chunkSizeBytes = 1 * 1024 * 1024;

  $file = new Google_DriveFile();
  $file->setTitle('My document');
  $file->setDescription('A test document');
  $file->setMimeType('text/plain');

  $media = new Google_MediaFileUpload('text/plain', null, true, $chunkSizeBytes);
  $media->setFileSize(filesize($filePath));

  $result = $service->files->insert($file, array('mediaUpload' => $media));

  $status = false;
  $handle = fopen($filePath, "rb");
  while (!$status && !feof($handle)) {
    $chunk = fread($handle, $chunkSizeBytes);
    $uploadStatus = $media->nextChunk($result, $chunk);
  }

  fclose($handle);
}
Chirag Shah
  • 3,654
  • 22
  • 29
  • This works perfectly and was very useful when another developer implemented with a Simple File uploader that was causing memory issues. This implementation allows for us to never go above 700MB of memory used, even with 10 simultaneous uploads of 2-5GB. Excellent! – Stephan Dec 18 '17 at 02:37
6

This may be a newer reference, but here is Google's official take on this question: https://developers.google.com/api-client-library/php/guide/media_upload

From the article:

Resumable File Upload

It is also possible to split the upload across multiple requests. This is convenient for larger files, and allows resumption of the upload if there is a problem. Resumable uploads can be sent with separate metadata.

$file = new Google_Service_Drive_DriveFile();
$file->title = "Big File";
$chunkSizeBytes = 1 * 1024 * 1024;

// Call the API with the media upload, defer so it doesn't immediately return.
$client->setDefer(true);
$request = $service->files->insert($file);

// Create a media file upload to represent our upload process.
$media = new Google_Http_MediaFileUpload(
  $client,
  $request,
  'text/plain',
  null,
  true,
  $chunkSizeBytes
);
$media->setFileSize(filesize("path/to/file"));

// Upload the various chunks. $status will be false until the process is
// complete.
$status = false;
$handle = fopen("path/to/file", "rb");
while (!$status && !feof($handle)) {
  $chunk = fread($handle, $chunkSizeBytes);
  $status = $media->nextChunk($chunk);
 }

// The final value of $status will be the data from the API for the object
// that has been uploaded.
$result = false;
if($status != false) {
  $result = $status;
}

fclose($handle);
// Reset to the client to execute requests immediately in the future.
$client->setDefer(false);
Andrew Odri
  • 8,868
  • 5
  • 46
  • 55
  • Hi Andrew, I'm using this code but I have no idea how I should make requests to get chunk status to handle resuming an interrupted upload and showing the progress, this code returns $status only when the whole file is uploaded. – Ramtin Gh Sep 06 '15 at 08:26
  • Hey @RamtinGh; from what I can tell, the `Google_Http_MediaFileUpload` class handles all of that for you; the source for the `nextChunk()` function appears to see if complete chunks have already been uploaded based on the HTTP response from the server, and if so, it skips over to the next chunk until it hits one that needs to be uploaded: https://github.com/google/google-api-php-client/blob/master/src/Google/Http/MediaFileUpload.php#L128 – Andrew Odri Sep 08 '15 at 17:26
  • Thanks @Andrew, I'm aware that client library handles this, but using this code, there is no way of getting chunk status unless the whole file is uploaded, the class uses it to see if upload is completed. to resume interrupted upload, I need to make a request to see how many bytes is sent, library does not do this by itself, if connection is interrupted, script will stop executing and I dont know how to resmue. – Ramtin Gh Sep 08 '15 at 17:35
  • I have posted a question, would you please have a look: http://stackoverflow.com/questions/32379007/make-requests-and-handle-responses-for-resumable-upload-google-drive-api-php – Ramtin Gh Sep 08 '15 at 17:37