on output when open page -
File ID: 1qG8tteyVhAbB_rbu_VUvaE9ReqnSjEAh...
But on google drive no new files are created. I want upload file to cron but now i want only download test.pdf and end.
require_once './google-api-php-client/vendor/autoload.php';
use Google\Client;
use Google\Service\Drive;
function uploadBasic()
{
try {
$client = new Client();
//$client->useApplicationDefaultCredentials();
$client->setAuthConfig('./google-api-php-client/1710-6c50418be6b2.json');
$client->addScope(Drive::DRIVE);
$driveService = new Drive($client);
$fileMetadata = new Drive\DriveFile(array(
'parents' => ['225qhcKKyf8Ot0IhrRxRtqgHNTxLV1LiyI'],
'name' => 'test.pdf',
'mimeType' => 'application/pdf'));
$mimeType=mime_content_type($fileMetadata);
$content = file_get_contents('https://example.com/test.pdf');
$file = $driveService->files->create($fileMetadata, array([
'data' => $content,
'mimeType' => 'application/pdf',
'uploadType' => 'multipart',
'fields' => 'id']));
printf("File ID: %s\n", $file->id);
return $file->id;
} catch(Exception $e) {
echo "Error Message: ".$e;
}
}
uploadBasic();
how to debug issue
The fastest way to debug this is to do a File.list. This will tell you if in fact the file was uploaded.
You are not setting parents yin your meta data, so the file will have been uploaded to the root directory.
service account
Remember if you are using a service account that the files are uploaded into the service accounts google drive account, not your personal drive account.
To upload to your personal drive account you would need to create a directory on your drive account, share that directory with your service account using the service account email address. The service account email address can be found in the json key file its the only one with an #.
Then set parents in the meta data to the folder on your drive account
$fileMetadata = new Drive\DriveFile(array(
'parents' => { 'FolderId' }
'name' => 'ASB-Background-3.png'));
File 0 size error after edit
You edited your question. It originally stated you were doing this
$content = file_get_contents('./google-api-php-client/ASB-Background-3.png');
It is bad practice to update your question and change your code. It changes the answer to your question and in this case your error message.
That being said From the documentation for file_get_contents
file_get_contents — Reads entire file into a string
There is nothing in the documentation that states that this method could load a file from a url. So your edit changing to a URL is probably not going to work.
file_get_contents('https://example.com/test.pdf');
Your file is uploading with 0 because your not giving it a file. Download that file on to the machine running it and then send it, or write our own method which will accept a url and return a string file conents.
upload image
Files are uploaded in two parts first the fileMetadata and then the file itself.
MimeType must be properly set to that of the file you are uploading. file_get_contents will only work on a file that is currently accessible by your code.
If the file size is 0 make sure
to check the most recent uploaded file. every create will create a new file.
ensure that your code has access to the file you are uploading.
make sure the mimeType is correct.
Sample.
try {
$client = new Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Drive::DRIVE);
$driveService = new Drive($client);
$fileMetadata = new Drive\DriveFile(array(
'name' => 'photo.jpg'));
$content = file_get_contents('../files/photo.jpg');
$file = $driveService->files->create($fileMetadata, array([
'data' => $content,
'mimeType' => 'image/jpeg',
'uploadType' => 'multipart',
'fields' => 'id']));
printf("File ID: %s\n", $file->id);
return $file->id;
} catch(Exception $e) {
echo "Error Message: ".$e;
}
Related
I'm trying to get the file ID of a created file using the google drive API so I can then use that to delete files. Here is the code:
$file = new Google_Service_Drive_DriveFile();
$file->setName($fileName);
$file->setDescription('Volunteer Hours');
$file->setParents(array($folderId));
$data = file_get_contents($filePath);
$createdFile = $this->service->files->create($file, array(
'data' => $data,
'uploadType' => 'multipart'
));
Is there some kind of .id method where I can say:
$createdFileID = $createdFile.id;
I have looked into the google drive api but wasn't able to find any such method. The reason I want an id for an uploaded file is so I can delete files if I wanted to using that specific id
Ultimately, here is the function I'm trying to write:
// Deletes a specific file from a specific folder
function deleteFile($folderName, $fileID) {
}
This way, we are protected and delete the right file if there happens to be files with the same name in a given folder.
I believe your goal as follows.
You want to retrieve the file ID of the uploaded file on Google Drive using googleapis for php.
When the filename of $fileName is existing in the specific folder of $folderName, you want to delete the existing file.
Answer for Question 1:
In this case, how about the following modification?
From:
$createdFile = $this->service->files->create($file, array(
'data' => $data,
'uploadType' => 'multipart'
));
To:
$createdFile = $this->service->files->create($file, array(
'data' => $data,
'uploadType' => 'multipart'
));
$createdFileID = $createdFile->getId(); // Added
By this, the file ID of the uploaded file can be retrieved with $createdFileID.
Answer for Question 2:
When you want to delete the file using the filename and folder name at function deleteFile($folderName, $fileName) {}, how about the following sample script?
Sample script:
function deleteFile($folderName, $fileName) {
$client = getClient();
$drive = new Google_Service_Drive($client);
$res1 = $drive->files->listFiles(array("q" => "name='{$folderName}' and trashed=false"));
$folderId = $res1->getFiles()[0]->getId();
$res2 = $drive->files->listFiles(array("q" => "name='{$fileName}' and '{$folderId}' in parents and trashed=false"));
if (count($res2->getFiles()) == 0) {
// When the filename of $fileName is not existing,
// do something
} else {
$fileId = $res2->getFiles()[0]->getId();
$drive->files->delete($fileId);
}
}
In this case, when the filename of $fileName is existing in the specific folder of $folderName, the existing file is deleted.
References:
Files: delete
Added:
When you want to delete the file using the file ID, you can use the following script.
function deleteFile($fileID) {
$client = getClient();
$drive = new Google_Service_Drive($client);
$drive->files->delete($fileID);
}
In this case, $folderName is not required to be used. Because at Google Drive, all files has the unique file ID.
Since 2015 I have been using the Google Cloud Storage API now I have just updated the PHP client library with latest version and got some error when uploading a file to google cloud storage
my error
{
"domain":"global",
"reason":"invalid",
"message":"Content-Type specified in the upload (application/octet-stream) does not match Content-Type specified in metadata (image/jpeg). If it was a simple upload (uploadType=media), the Content-Type was specified as a bare header. If it was a multipart upload (uploadType=multipart), then the Content-Type was specified in the second part of the multipart. If it was a resumable upload (uploadType=resumable), then the Content-Type was specified with the X-Upload-Content-Type header with the start of the resumable session. For more information, see https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload."
}
And I also Need Help for resumable upload using google client api
My code to Upload File:
$storageObject->setContentType($image_type);
$storageObject->setName($name);
$storageObject->setSize(filesize($data["temp_name"]));
$storageObject->setMetadata($meta_data);
try{
$res = $storageService->objects->insert(
$data["bucket_name"],
$storageObject,
array(
'data' => file_get_contents($data["image_temp_name"]),
'uploadType' => 'multipart',
'predefinedAcl'=>'publicRead'
// 'contentEncoding'=>'gzip'
));
}
catch(Exception $e)
{
echo $e->getMessage();
}
I just Solved it by putting mimeType In Request Params
$storageObject->setContentType($image_type);
$storageObject->setName($name);
$storageObject->setSize(filesize($data["temp_name"]));
$storageObject->setMetadata($meta_data);
try{
$res = $storageService->objects->insert(
$data["bucket_name"],
$storageObject,
array(
'mimeType' => $image_type,
'data' => file_get_contents($data["image_temp_name"]),
'uploadType' => 'multipart',
'predefinedAcl'=>'publicRead'
// 'contentEncoding'=>'gzip'
));
}
catch(Exception $e)
{
echo $e->getMessage();
}
I am trying to create folder using google drive api. I am able to get file id at the end. but i am not able to my folder in google drive. it seems some permission issue?
$scopes = array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.appdata','https://www.googleapis.com/auth/drive.apps.readonly',
'https://www.googleapis.com/auth/drive.metadata','https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.readonly','https://www.googleapis.com/auth/drive.photos.readonly'
);
$creds = new Google_Auth_AssertionCredentials(
$serviceAccountName,
$scopes,
file_get_contents($keyFile)
);
$client = new Google_Client();
$client->setApplicationName($appName);
$client->setClientId($clientId);
$client->setAssertionCredentials($creds);
$service = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'Invoices',
'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1),
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array());
printf("File ID: %s\n", $file->id);
The files that are being created belong to the API account email (something like api-service-account#yourproject.iam.gserviceaccount.com. If you go to the drive URL:
https://docs.google.com/document/d/{ID}, you will get a "Permission Denied, request access" page.
The service account email is not related to your user email.
In order to create files with your user, you need to create an OAauth token authorization.
Create the OAuth credentials following the steps "Step 1: Turn on the Drive API" on this page
Modify your script, by following the example on this page, you can have:
use Google_Client;
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;
...
$file = 'root/to/your/credentials.json';
$client = new Google_Client();
$client->setScopes([
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.appdata',
'https://www.googleapis.com/auth/drive.apps.readonly',
'https://www.googleapis.com/auth/drive.metadata',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.readonly',
'https://www.googleapis.com/auth/drive.photos.readonly'
]);
$client->setAuthConfig($file);
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
// You will need to open this url
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
$accessToken = $client->authenticate($authCode);
file_put_contents($credentialsPath, $accessToken);
printf("Credentials saved to %s\n", $credentialsPath);
$client->setAccessToken(json_decode($accessToken, true));
$service = new Google_Service_Drive($client);
$metadata = new Google_Service_Drive_DriveFile([
'name' => 'testing drive',
'mimeType' => "application/vnd.google-apps.document"
]);
$file = $service->files->create($metadata, []);
print_r($file);
The file should be in your Drive home directory.
By the way, I suggest you try the new version google/apiclient:2.0.2 (which is still on Beta, but works okay).
Mayrop answer is partially right.
The files that are being created belong to the API account email (something like api-service-account#yourproject.iam.gserviceaccount.com.
You need to give permission to owner of that account like
$newPermission = new Google_Service_Drive_Permission();
$value="email id";
$type="user";
$role="writer";
$newPermission->setValue($value);
$newPermission->setType($type);
$newPermission->setRole($role);
try {
$res= $service->permissions->insert($fileId, $newPermission);
print_r($res);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
You will see that folder in Shared with me. You can also add in your drive manually.
You can also disable sending notification via email using
$service->permissions->insert($fileId, $newPermission,array('sendNotificationEmails'=>false));
Hope this will work for you.
Yes, It seems permissions issue. Try removing
'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1),
from
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'Invoices',
'permissions' => array('type'=>'anyone','role'=>'reader','allowFileDiscovery'=>1),
'mimeType' => 'application/vnd.google-apps.folder'));
so I have worked over it, and finally got the full working solution for Google Drive V3 in Php. As follows:
You can go through this gist for full code and better understanding:
https://gist.github.com/KartikWatts/22dc9eb20980b5b4e041ddcaf04caf9e
First of all adding to the answer from #Hitu Bansal:
This code works fine:
$this->newPermission = new Google_Service_Drive_Permission();
$value=<YOUR EMAIL ADDRESS>;
$type="user";
$role="reader";
$this->newPermission->setEmailAddress($value);
$this->newPermission->setType($type);
$this->newPermission->setRole($role);
$this->newPermission->allowFileDiscovery;
try {
$res= $this->service->permissions->create($folder_id, $this->newPermission);
print_r($res);
catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
If, instead you want to share the link with anyone: You may use
$type="anyone";
$this->newPermission->setType($type);
$this->newPermission->setRole($role);
$this->newPermission->allowFileDiscovery;
$this->newPermission->view;
NOTE:
In this case, setEmailAddress() shall be removed.
IMPORTANT: In case of 'anyone', the folder will not be visible in your personal drive for sure, but you can still visit and interact with the folder as per given roles by visiting the link making use of the folder_id that you know already. So, you can visit the link as: https://drive.google.com/drive/u/5/folders/**{folder_id}** It will be publically accessible now.
For more clear reference to the parameters along with a description, this is really helpful: https://developers.google.com/drive/api/v3/reference/permissions#methods
NOTE: In my personal opinion, a better way to work with Google Drive API is to create the folder first manually (if workflow allows it), then upload the files using the folder_id of that created folder. Remember, In case folder is created manually, permission shall be provided to the Service Account email-id before.
While permission issue is the main cause of this problem. What I did to make the folders or files appear after I uploaded it with service account was to specify the parent folder. If you upload / create folder / files without parent folder ID, that object's owner will be the service account that you are using.
By specifying parent ID, it will use the inherited permissions.
Here's the code I use in php (google/apiclient)
$driveFile = new Google\Service\Drive\DriveFile();
$driveFile->name = 'New Folder';
$driveFile->mimeType = 'application/vnd.google-apps.folder';
$driveFile->parents = ['123456789qwertyuiop'];
$result = $service->files->create($driveFile);
Using the code below
define('DRIVE_SCOPE', 'https://www.googleapis.com/auth/drive');
define('SERVICE_ACCOUNT_EMAIL', 'xxx.iam.gserviceaccount.com');
define('SERVICE_ACCOUNT_PKCS12_FILE_PATH', 'xxx');
function buildService($userEmail) {
$key = file_get_contents(SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_Auth_AssertionCredentials(
SERVICE_ACCOUNT_EMAIL,
array(DRIVE_SCOPE),
$key);
//$auth->sub = $userEmail;
$client = new Google_Client();
$client->setAssertionCredentials($auth);
return new Google_Service_Drive($client);
}
$service = buildService('xxx.apps.googleusercontent.com');
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'Invoices',
'mimeType' => 'application/vnd.google-apps.folder'
));
$file = $service->files->create($fileMetadata, array(
'fields' => 'id'
));
printf("Folder ID: %s\n", $file->id);
I have been trying to create a folder on my drive account through PHP. I believe everything is configured correctly and I am getting a result
Folder ID: 0B2nllBpB_k0NQWFNUjlSc0NUdE0
But the folder is not being created on my drive account. The same goes with creating files as well. It keeps returning an ID but nothing is actually created. What exactly am I doing wrong?
Your current code is authenticating as the service account and creating a file. The resultant file would then only be accessible to the service account, not your Google user. You can confirm this by doing a list of files instead of a create in your code, you'll get back the files you've previously created.
Your code has sub= commented out. Uncommented that line and make sure you've followed the domain-wide delegation instructions so that your code can authenticate and act as your Google user.
I'm trying to upload a local CSV-file to Google Drive and display it like a Google Spreadsheet there. However, when I go to my Google Drive and click the link to my file, I can only download it, not view it as a spreadsheet. I've tried using the ?convert=true but the file doesn't get converted. I've also tried using application/vnd.google-apps.spreadsheet as the mime type but noting changes or I get a 400 Bad request response.
When I right click the file, I can choose to open with Google Spreadsheets which then displays the file correctly. I can't find anything about this in the current documentation over at Google and searches on google haven't help a whole lot.
What I've done so far is creating a new, empty Google spreadsheet and tried filling it with my CSV file but that gives me a 500 Internal Error.
$file = new Google_DriveFile();
$file->setTitle('Exported data from ' . $this->event->title);
$file->setDescription('Exported data from ' . $this->event->title);
$file->setMimeType( 'text/csv' );
try {
$createdFile = $this->drive->files->insert($file, array(
'data' => $data,
'mimeType' => 'application/vnd.google-apps.spreadsheet'
), array('convert'=>true));
// Uncomment the following line to print the File ID
// print 'File ID: %s' % $createdFile->getId();
$additionalParams = array(
'newRevision' => false,
'data' => $data,
'convert'=>true //no change if this is true or false
);
$newFile = $this->drive->files->get( $createdFile->getId() );
$newFile->setMimeType('text/csv');
$updated = $this->drive->files->update($createdFile->getId(), $newFile, $additionalParams);
preint_r($updated);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
I've looked at the API for Google Drive but haven't found anything useful. I'm wondering if I should use the Google Spreadsheets API or is the Google Drive API the one to use solely?
Many thanks in advance,
Waldemar
Try the following. It's from the File:insert reference in the Google documentation but I added the convert parameter:
/**
* Insert new file.
*
* #param Google_DriveService $service Drive API service instance.
* #param string $title Title of the file to insert, including the extension.
* #param string $description Description of the file to insert.
* #param string $parentId Parent folder's ID.
* #param string $mimeType MIME type of the file to insert.
* #param string $filename Filename of the file to insert.
* #return Google_DriveFile The file that was inserted. NULL is returned if an API error occurred.
*/
function insertFile($service, $title, $description, $parentId, $mimeType, $filename) {
$file = new Google_DriveFile();
$file->setTitle($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->insert($file, array(
'data' => $data,
'mimeType' => $mimeType,
'convert' => true,
));
// Uncomment the following line to print the File ID
// print 'File ID: %s' % $createdFile->getId();
return $createdFile;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
i am try above code it will not working for me
it will just stop after login
just use
$file->setMimeType('application/vnd.google-apps.spreadsheet);
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => 'text/csv',
'convert' => true,
));
it will work for me
I have to add another parameters to make it work.
'uploadType' => 'multipart'
$createdFile = $service->files->insert($file,array(
'data' => $data,
'mimeType' => 'text/csv',
'convert' => true,
'uploadType' => 'multipart',
));
Now it's working.