Files updates no longer works using the google-api-php-client - php

I have a very small script that uploads and / or update files (wrote this about 1 year ago, borrowed 80% of the lines from the examples)
No major changes in the code since march (using 1.0.0-alpha) but mid-may the file updates stopped working, raising an Internal Server Error , i upgraded to 1.0.4-beta with no success :
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling PUT https://www.googleapis.com/upload/drive/v2/ [...] (500) Internal Error' in
google-api-php-client-1.0.4-beta/src/Google/Http/REST.php:80
code:
$client->setDefer(true);
$request = $service->files->update($update_id,$file);
$media = new Google_Http_MediaFileUpload(
$client,
$request,
'text/plain',
null,
true,
$chunkSizeBytes
);
$media->setFileSize(filesize($csvfile))
$status = false;
$handle = fopen($csvfile, "rb");
while (!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
File inserts (HTTP POST) are still working (using the same code for uploading the chunks)
any ideas ?

I can update a file ( previously created or copied from a template ) with this code :
(...)
require_once 'src/Google/Client.php';
require_once 'src/Google/Service/Oauth2.php';
require_once 'src/Google/Service/Drive.php';
(...)
$client = new Google_Client();
// set scopes ...
(...)
$GDrive_service = new Google_Service_Drive($client);
(...)
// then I set parameters
(...)
$newTitle = $title ;
$newDescription = $description ;
$newMimeType = 'text/csv' ;
$newFileName = $filename ;
$service = $GDrive_service ;
(...)
$updatedFile = updateFile($service, $fileId, $newTitle, $newDescription, $newMimeType, $newFileName, $newRevision) ;
function updateFile($service, $fileId, $newTitle, $newDescription, $newMimeType, $newFileName, $newRevision) {
try {
// First retrieve the file from the API.
$file = $service->files->get($fileId);
// File's new metadata.
$file->setTitle($newTitle);
$file->setDescription($newDescription);
$file->setMimeType($newMimeType);
// File's new content.
$data = file_get_contents($newFileName);
$convert = 'true' ;
$additionalParams = array(
'uploadType' => 'multipart',
'newRevision' => $newRevision,
'data' => $data,
'mimeType' => $newMimeType,
'convert' => $convert,
);
// Send the request to the API.
$updatedFile = $service->files->update($fileId, $file, $additionalParams);
return $updatedFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
(...)
// this is info of the updated file
$fileId = $updatedFile->getId() ;
// link of file
$cF_link = $updatedFile->alternateLink ;
// pdf version
$enllacos = $updatedFile->exportLinks ;
$cF_PDF_link = $enllacos['application/pdf'] ;
(...)
This code is working with the 1.0.5-beta php client
Sergi

Related

Problem with upload image to google drive using php

On my site I use google api to upload images in folder. Actually, there is no official documentation from google how to use api using php, only python, js and etc. Current problem is that I get no errors, but file isn't uploading. I'm 100% sure that my service workers work (sorry for such bad english) properly. Below I put my php code for uploading images:
<?php
include '../vendor/autoload.php';
function handleGoogleDrive($file)
{
//connecting to google drive
$client = new \Google_Client();
$client->setApplicationName('Somesite');
$client->setScopes([\Google_Service_Drive::DRIVE]);
$client->setAccessType('offline');
$client->setAuthConfig('./credentials.json');
$client->setClientId('2445617429-6k99ikago0s0jdh5q5k3o37de6lqtsd3.apps.googleusercontent.com');
$client->setClientSecret('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');
$service = new Google_Service_Drive($client);
//counting amount of files in folder, there is no real reason in doing that
//it is just a test of connecting
$folder_id = '1eQtNOJjlA2CalZYb90bEs34IaP6v9ZHM';
$options = [
'q' => "'" . $folder_id . "' in parents",
'fields' => 'files(id, name)'
];
//printing result
$results = $service->files->listFiles($options);
echo count($results->getFiles());
//trying to add file
$data = file_get_contents("../test.jpg");
$file = new Google_Service_Drive_DriveFile();
$file->setName(uniqid(). '.jpg');
$file->setDescription('A test document');
$file->setMimeType('image/jpeg');
$new_file = $service->files->create($file, [
'data' => $data,
'mimeType' => 'image/jpeg',
'uploadType' => 'multipart',
]);
print_r($new_file);
}
This is my standard upload code for uploading.
Try removing 'uploadType' => 'multipart', in your code.
I also cant see you setting the folder id when you upload your file which means its going to root directory.
// Upload a file to the users Google Drive account
try{
$filePath = "image.png";
$folder_id = '1eQtNOJjlA2CalZYb90bEs34IaP6v9ZHM';
$fileMetadata = new Drive\DriveFile();
$fileMetadata->setName("image.png");
$fileMetadata->setMimeType('image/png');
$fileMetadata->setParents(array($folder_id));
$content = file_get_contents($filePath);
$mimeType=mime_content_type($filePath);
$request = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'fields' => 'id'));
printf("File ID: %s\n", $request->id);
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
Remember if you are using a service account, files are uploaded to the service accounts drive account unless you add the folder you want to upload the file to.
files list
// Print the next 10 events on the user's drive account.
try{
$optParams = array(
'pageSize' => 10,
'fields' => 'files(id,name,mimeType)'
);
$results = $service->files->listFiles($optParams);
$files = $results->getFiles();
if (empty($files)) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($files as $file) {
$id = $file->id;
printf("%s - (%s) - (%s)\n", $file->getId(), $file->getName(), $file->getMimeType());
}
}
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
Using the code which was suggested to me, this is full solution.
(Thanks everybody who helped me)
<?php
include '../vendor/autoload.php';
function handleGoogleDrive($file)
{
//connecting to google drive
$client = new \Google_Client();
$client->setClientId('YOUR ID IN SECRET FILE');
$client->setClientSecret(YOUR SECRET IN JSON FILE);
$client->setRedirectUri(YOUR REDIRECT URI);
//you should register redirect uri
$client->setApplicationName('Somesite');
$client->setScopes([\Google_Service_Drive::DRIVE]);
$client->setAuthConfig('./credentials.json');
$service = new Google_Service_Drive($client);
try{
$filePath = "../test.jpg";
$folder_id = 'YOUR FOLDER ID';
$fileMetadata = new Google_Service_Drive_DriveFile();
$fileMetadata->setName("image.png");
$fileMetadata->setMimeType('image/png');
$fileMetadata->setParents(array($folder_id));
$content = file_get_contents($filePath);
$mimeType=mime_content_type($filePath);
$request = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'fields' => 'id'));
printf("File ID: %s\n", $request->id);
}
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
try{
$optParams = array(
'pageSize' => 10,
'fields' => 'files(id,name,mimeType)'
);
$results = $service->files->listFiles($optParams);
$files = $results->getFiles();
if (empty($files)) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($files as $file) {
$id = $file->id;
printf("%s - (%s) - (%s)\n", $file->getId(), $file->getName(), $file->getMimeType());
}
}
}
catch(Exception $e) {
// TODO(developer) - handle error appropriately
echo 'Message: ' .$e->getMessage();
}
}

Using the Google Drive API for PHP, What is the proper way to upload a file while setting the "keepRevisionForever" to true?

I am trying to allow file uploads to overwrite the previous copy and keep the revision history permanent within Google Drive. Also...Do I need to upload with a set ID or is the file name going to overwrite natively?
Here is a sample of what I have as a test function:
function uploadFile($filename = "")
{
$title="testFile";
$description="Testing the upload of the file";
$mimeType="image/jpeg";
$filename = ROOTPATH."IMG_1232.JPG"; //Temporarily overriding $filename for testing.
$file = new Google_Service_Drive_DriveFile();
$file->setName($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new Google_Service_Drive_ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$this->startGDService();
$createdFile = $this->service->files->create($file, array(
'data' => $data,
'mimeType' => $mimeType,
'keepRevisionForever' => true // <---This doesn't seem to work.
));
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
return;
}
Looks like I was using the wrong function. The create function will always create a file on the drive. To overwrite a particular file, you need to use the update() function. See here:
function updateFile($filename, $fileID)
{
$this->startGDService();
$filename = UPLOAD_PATH.$filename;
$mimetype = mime_content_type ($filename);
try {
$emptyFile = new Google_Service_Drive_DriveFile();
$data = file_get_contents($filename);
$this->service->files->update($fileID, $emptyFile, array(
'data' => $data,
'mimeType' => $mimetype,
'uploadType' => 'multipart',
'keepRevisionForever' => true
));
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

Send large attachment with Gmail API

According to Gmail API to send an email with large attachments bigger then 5MB you need to use the instructions here:
https://developers.google.com/gmail/api/guides/uploads
The API is a not very clear about the details and I tried to use the explanation I found here:
Gmail API PHP Client Library - How do you send large attachments using the PHP client library?
I get "Entity too large" error message every time.
Someone can succeded to send an attachment bigger than 5MB with Gmail API, and help me understand what I'm doing wrong?
My composer file:
{
"require": {
"google/apiclient": "^2.0",
"pear/mail_mime": "^1.10"
}
}
My code after reading everything is this:
<?php
set_time_limit(100);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
require_once __DIR__ . '/vendor/autoload.php';
require_once 'client.php';
$googleClient = getClient();
$mailService = new Google_Service_Gmail($googleClient);
$message = new Google_Service_Gmail_Message;
$file = __DIR__ . '/pexels-photo.jpg';
$mime = new Mail_mime;
$mime->addTo('mymail#domain.com');
$mime->setTXTBody('');
$mime->setSubject('test');
$mailMessage = base64_encode($mime->getMessage());
$message->setRaw($mailMessage);
$request = $mailService->users_messages->send(
'me',
$message,
array( 'uploadType' => 'resumable' )
);
$googleClient->setDefer(true);
$media = new Google_Http_MediaFileUpload(
$googleClient,
$request,
'message/rfc822',
$mailMessage,
$resumable = true,
$chunkSizeBytes = 1 * 1024 * 1024
);
$media->setFileSize(filesize($file));
$status = false;
$handle = fopen($file, 'rb');
while (! $status && ! feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
fclose($handle);
$googleClient->setDefer(false);
#MP In my case, the problem is that I needed to set the unencoded message size, not the actual file. like this:
$media->setFileSize(strlen($message));

Insert object to Google Cloud Storage at specific route using PHP

I am amazed by the lack of information at the official documentation of Google Cloud Storage with PHP.
Here we go... I'm trying to manage bucket's uploads and downloads with Google APIs Client Library for PHP, but I can't find anywhere the way to specify to the API where I want to upload my files at google's bucket (I can only upload them at bucket's root).
Here's the code that I'm using for the upload (extracted from https://github.com/guillefd/Backup-manager-gcs/blob/master/application/libraries/Googlecloudstorage.php):
public function media_file_upload($file_path = null, $file_name = null) {
# init
$result = new stdClass();
$result->error = null;
$result->status = null;
$result->exception = null;
# timer
$result->starttime = microtime();
# init gcs api
$gso = new Google_Service_Storage_StorageObject();
$gso->setName($file_name);
$gso->setBucket($this->bucket);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo,$file_path);
$chunkSizeBytes = 1 * 1024 * 1024;
$this->client->setDefer(true);
$filetoupload = array(
'name'=>$file_name,
'uploadType'=>'resumable'
);
# service
$this->newStorageService();
$status = false;
# try
try {
$request = $this->storageService->objects->insert($this->bucket, $gso, $filetoupload);
$media = new Google_Http_MediaFileUpload($this->client, $request, $mimetype, null, true, $chunkSizeBytes);
$media->setFileSize(filesize($file_path));
$handle = fopen($file_path, "rb");
# loop chunks
while(!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
fclose($handle);
$this->client->setDefer(false);
// $result->status = $status;
} catch(Exception $e) {
$result->error = true;
$result->status = 'Google Cloud Service upload failed';
$result->exception = $e;
}
# timer
$result->endtime = microtime();
$result->totaltime = $this->get_totaltime($result);
# verify response
$result->httpcode = http_response_code();
$result->error = isset($status->kind) && $status->kind==self::STORAGE_OBJECT ? false : true;
return $result;
}
The main question that I'm actually asking is: Is there a way to upload files to google's bucket at a specific route, using Google Cloud's PHP API?
Thanks!

Google API PHP Update File

I'm trying to update the content of the file. Use the PHP function:
function updateFile($service, $fileId, $newTitle, $newDescription, $newMimeType, $newFileName, $newRevision) {
try {
// First retrieve the file from the API.
$file = $service->files->get($fileId);
// File's new metadata.
$file->setTitle($newTitle);
$file->setDescription($newDescription);
$file->setMimeType($newMimeType);
// File's new content.
$data = file_get_contents($newFileName);
$additionalParams = array(
'newRevision' => $newRevision,
'data' => $data,
'mimeType' => $newMimeType
);
// Send the request to the API.
$updatedFile = $service->files->update($fileId, $file, $additionalParams);
return $updatedFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
....
$data = retrieveAllFiles($service);
$fileName = 'test.txt';
$mimeType = mime_content_type('./'.$fileName);
$res = updateFile($service, $data[0]['id'], $data[0]['title'], 'update', $mimeType, $fileName, true);
I'm trying to add a text file line "test string". Function updates the data file (description, lastModifyingUser...), but the content of the file remains the same. Who can tell what's wrong?
In additionalParams need to add :
'uploadType' => 'multipart',
or
'uploadType' => 'media',
Hope it helps!

Categories