Google Drive Api PHP multipart upload empty content - php

my issue is the following.
When using the google drive api V3 and php to upload a file to google drive, the file uploaded is empty, with a filesize of 0 bytes. All the metadata uploads no problem.
session_start();
$file_tmp=$_SESSION['file_tmp'];
$drive = new Google_Service_Drive($client);
$data = file_get_contents($file_tmp);
$file = new Google_Service_Drive_DriveFile(array(
'data' => $data,
'mimeType' => $file_type,
'name' => $file_name,
'description'=>$lolol,
'uploadType' => 'multipart',
'parents' => array($folderID),
'uploadType' => 'multipart'
));
$createdFile = $drive->files->create($file);
For anyone wondering, if I echo $file_tmp I get a path such as /private/var/tmp/phpDpmi83 .(I got this from a html form with input type file)
Originally i didn't have an UploadType and other forums said that was the issue, but I added that and still nothing.
Any suggestions?

I believe your goal as follows.
You want to upload a file with multipart/form-data to the specific folder in Google Drive using Drive API.
You want to achieve this using googleapis for PHP.
In your script, $drive can be used for uploading the file.
For this, how about this answer?
Modification point:
In your script, please separate the metadata and file content. By this, I think that your script works.
When above point is reflected to your script, it becomes as follows.
Modified script:
session_start();
$file_tmp=$_SESSION['file_tmp'];
$drive = new Google_Service_Drive($client);
$data = file_get_contents($file_tmp);
// I modified below script.
$file = new Google_Service_Drive_DriveFile(array(
'mimeType' => $file_type,
'name' => $file_name,
'description'=>$lolol,
'parents' => array($folderID),
));
$file_content = array(
'data' => $data,
'uploadType' => 'multipart'
);
$createdFile = $drive->files->create($file, $file_content);
Note:
In this modification, it supposes that $data is the file content. If your $file_tmp cannot be used, please test using a sample file.
In this case, the maximum file size is 5 MB. Please be careful this.
References:
Upload file data
googleapis for PHP

Related

Drive API uploaded file always has zero size with PHP client

I'm trying to upload files into a google drive in a specific folder using a service account. It all appears to work - but the files always show up with 0 size. I've found a couple of very similar questions on here but none of the answers have worked.
The code I'm using is:
putenv('GOOGLE_APPLICATION_CREDENTIALS = ' . $home_path . '../google-oauth-credentials.json');
try {
$gclient = new Google\Client();
$gclient->useApplicationDefaultCredentials();
$gclient->addScope('https://www.googleapis.com/auth/drive');
$driveService = new Google\Service\Drive($gclient);
$content = file_get_contents('testfile.txt');
$fileMetadata = new Google\Service\Drive\DriveFile(array(
'name' => 'test.txt',
'parents' => array('{PARENT_ID}'),
'description' => 'Test Description'
));
$file = $driveService->files->create($fileMetadata, array([
'data' => $content,
'mimeType' => 'text/plain',
'uploadType' => 'multipart',
'fields' => 'id'
]));
printf("File ID: %s\n", $file->id);
echo '<br>';
echo '<pre>' . print_r($file,1) . '</pre>';
echo '<h1>Content:</h1>';
echo ($content);
} catch(Exception $e) {
echo "Error Message: ".$e;
};
With {PARENT_ID} being the ID of the folder the files should be saved in.
This is meant to be uploading pdf files but I've switched to a simple text file to rule out a mime issue. With the PDF's I was using "application/pdf" as the mimeType, I've also tried "application/octet-stream" for both pdf and text and I've tried putting the mimeType in the $fileMetaData as well as in the request body as it currently is.
I've tried using 'uploadType' of 'media' as well as some other answers had suggested.
I've also tried with and without the 'fields' => 'id' whose purpose I can't seem to find in the API docs - but which was shown in various examples and other answers. I get the same results with or without it.
No luck. With any of that I get files with correct meta data....but they never have any content and are just 0 bytes in size.
I added the lines echoing out $content to confirm that file_get_contents is loading the correct file and its content to rule out a problem with what I'm passing to the request.
I'm loading the google api client through composer with
composer require google/apiclient:^2.12.1
And it seems to be working correctly as I can create google sheets, and edit their contents as well as create files...just the files always wind up having 0 size.
Try dropping the 'uploadType' => 'multipart',
// Upload a file to the users Google Drive account
try{
$filePath = "image.png";
$fileMetadata = new Drive\DriveFile();
$fileMetadata->setName('testfile.txt');
$fileMetadata->setMimeType('text/plain');
$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();
}
I found the problem.
The error was in:
$file = $driveService->files->create($fileMetadata, array([
'data' => $content,
'mimeType' => 'text/plain',
'uploadType' => 'multipart',
'fields' => 'id'
]));
Which came more or less verbatim from:
https://developers.google.com/drive/api/guides/manage-uploads
I'm also not sure why the 'fields' parameter is included since v3 create doesn't appear to support that.
Note the "array([])" It's defining an array inside the array.
Removing the [] or the array() solves the problem by correctly passing the intended array instead of passing an array containing the intended array.

Can we insert html contents into google docs using google docs api with PHP?

I am working on google docs api with PHP code. I want to insert html contents into google docs. Is there any way doing this and if yes, How we can achieve that as I have searched a lot but couldn't found a proper answer or solution to this problem.
I believe your goal is as follows.
You want to upload an HTML file to Google Drive by converting it to Google Document using googleapis for PHP.
In this case, how about the following sample script?
Sample script:
$service = new Google_Service_Drive($client); // Please use your authorization script.
$html_file = "./sample.html"; // Please set the filename with the path of HTML file.
$folder_id = "###"; // Please set the folder ID you want to put.
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'sample',
'parents' => [$folder_id ],
'mimeType' => 'application/vnd.google-apps.document'
));
$res = $service->files->create($fileMetadata, array(
'data' => file_get_contents($html_file),
'mimeType' => 'text/html',
'uploadType' => 'multipart',
'fields' => 'id'
));
$file_id = $res->getId();
print($file_id);
In this script, the HTML file is uploaded to Google Drive, and the HTML data is converted to Google Document.
Reference:
Upload file data

Is there a way to create Google document in specific folder of Google Drive through Google API PHP SDK?

I've checked updating permissions per user or group, but it doesn't seem viable in my case because users, who will be creating docs from application, won't be added manually. Is there are way to specify folder (other than root in Google Drive) that will be used with every insert request to place document in it?
You need to set the folder id of the directory you would like the file created in as the parents in the metadata.
$service = new Google_DriveService($client);
// Create the file on your Google Drive
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'My file',
'parents' => ['FILEIDOFFOLDER']));
$content = file_get_contents($target_file);
$mimeType=mime_content_type($target_file);
$file = $driveService->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'fields' => 'id'));
printf("File ID: %s\n", $file->id);

Google Drive API: Why doesn't uploaded file appear in my Google Drive until I view the webContentLink

I am new to the Google Drive API and have gotten to the point where I have successfully uploaded a file and subsequently am able to list out the file(s) that I uploaded. Something that confused me was that files I uploaded did NOT appear in my Google Drive until I viewed the file via the webContentLink address. Only after viewing the file in a browser via the webContentLink address did the file then magically appear in my Google Drive.
I have seen similar questions on stackoverflow but those seem to be related to the fact that a parent ID was not specified in the upload. I am just curious as to why the file doesn't appear in my Google Drive unless I view the file separately via the webContentLink link. Here is my upload code:
function insertFile($service, $title, $description, $parentId, $mimeType, $filename)
{
$file = new Google_Service_Drive_DriveFile();
$file->setName($title);
$file->setDescription($description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($parentId != null) {
$parent = new ParentReference();
$parent->setId($parentId);
$file->setParents(array($parent));
}
try {
$data = file_get_contents($filename);
$createdFile = $service->files->create($file, array('data' => $data, 'mimeType' => $mimeType));
$Permission = new \Google_Service_Drive_Permission(array(
'type' => 'anyone',
'role' => "reader",
'additionalRoles' => []
));
$service->permissions->create(
$createdFile->getId(), $Permission, array('fields' => 'id'));
return $createdFile;
} catch (Exception $e) {
die("An error occurred: " . $e->getMessage());
}
}
$title="Berkobien Tree";
$description="BerkobienTree upload";
$parentId=null;
$mimeType='application/pdf';
$filename='D:\WWWRoot\babycity.com\httpdocs\BerkobienTree.pdf';
$createdFile = insertFile($service, $title, $description, $parentId, $mimeType, $filename);
it's most likely due to some latence coming from your connection.
When I upload new files, or move files between drives with the API it most often appears instantly, but some other times it takes a few seconds (not more than one minute though). But if you refresh your drive's page emptying cache it should do the trick.
When I create a folder I simply give these informations :
$folderFile = new \Google_Service_Drive_DriveFile([
'name' => $folderName,
'mimeType' => 'application/vnd.google-apps.folder',
'parents' => [$receivingFolderId],
'id' => $service->files->generateIds(['count' => 1, 'space' => 'drive']),
]);
$service->files->create($folderFile, [
'includePermissionsForView' => 'published',
'supportsAllDrives' => true,
]);
and for creating a file / copying a file
// Create new file with seedFile's name and mimeType
$newFile = new \Google_Service_Drive_DriveFile([
'name' => $name,
'mimeType' => $mimeType,
'parents' => [$PARENT_ID],
]);
// Copy the original file data into the newly created file
$service->files->copy($originalFileId, $newFile, [
'supportsAllDrives' => true,
]);
/*
So because I'm using a Team drive and an external drive for this process
I do not have the rights to delete a file from an external drive so I simply remove its parent, and the file is now an 'orphan'.
It is not a suppression of the file !
In my case it fits my needs.
*/
// Remove the original file's parent folder to delete it from his folder
$service->files->update($originalFileId, (new \Google_Service_Drive_DriveFile()), [
'includePermissionsForView' => 'published',
'removeParents' => $originalFileId->getParents(),
'supportsAllDrives' => true,
]);
As you mentioned, you already can create a file, and from your code I can see that it works. So I think your problem just comes from a latence in your internet connection ? Maybe try to set the parent a different way ? I'm just speculating at this point.

Can i upload a password protected pdf using google drive api?

So i've tried uploading a normal non password protected pdf file and it successfully gets uploaded using the below code.
However if i try the same with a password protected file google throws a 400 error code (Bad Request)
refrence: https://developers.google.com/drive/api/v3/reference/files/create
$content = file_get_contents($file_path);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'dummy_name',
'mimeType' => 'application/vnd.google-apps.spreadsheet'));
$file = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => 'application/pdf',
'uploadType' => 'multipart',
'fields' => 'id'));
Is it possible to upload a pdf with password protection even if i have the password with me?
You seem to have the mimeType set to "application/vnd.google-apps.spreadsheet".
I think it should work if you set it to "application/pdf"
In my case, password protected file upload seems to work with PDFs, but not with DOCX files.

Categories