When I did a basic file upload & set the permission like so, it worked great:
$file = $service->files->create($fileMetadata, array(
'data' => $content,
'mimeType' => $mimeType,
'uploadType' => 'multipart',
'fields' => 'id'));
$permissions = new Google_Service_Drive_Permission(array(
"role" => "reader",
"type" => "anyone",
));
$setPermission = $service->permissions->create($file->id, $permissions);
But when I upload a large file that's split into chunks & use the resumable uploadType, the permissions aren't set on the file & I don't get any errors:
$service = new Google_Service_Drive($client);
$file = new Google_Service_Drive_DriveFile();
$file->title = $fileName;
$file->name = $fileName;
$chunkSizeBytes = 1 * 1024 * 1024;
$mimeType = mime_content_type($fullpath);
// Call the API with the media upload, defer so it doesn't immediately return.
$client->setDefer(true);
$request = $service->files->create($file);
// Create a media file upload to represent our upload process.
$media = new Google_Http_MediaFileUpload(
$client,
$request,
$mimeType,
null,
true,
$chunkSizeBytes
);
$media->setFileSize(filesize($fullpath));
// Upload the various chunks. $status will be false until the process is complete.
$status = false;
$handle = fopen($fullpath, "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;
error_log($result->id);
}
fclose($handle);
$permissions = new Google_Service_Drive_Permission(array(
"role" => "reader",
"type" => "anyone"
));
$setPermission = $service->permissions->create($result->id, $permissions);
Any suggestions on what I'm doing wrong?
I have had the same situation with you. In that case, when the file information is retrieved with $res = $service->files->get($result->id); after the file was uploaded with the resumable upload, the empty object of {} is returned without error. I thought that this is the reason of the issue.
So, I used the following workaround. In this workaround, after the file was uploaded with the resumable upload, I retrieved $client again. By this, $res = $service->files->get($result->id); worked after the file was uploaded. When this is used for your script, please modify as follows.
From:
fclose($handle);
$permissions = new Google_Service_Drive_Permission(array(
"role" => "reader",
"type" => "anyone"
));
$setPermission = $service->permissions->create($result->id, $permissions);
To:
fclose($handle);
$client = getClient(); // <--- Added
$service = new Google_Service_Drive($client); // <--- Added
$permissions = new Google_Service_Drive_Permission(array(
"role" => "reader",
"type" => "anyone"
));
$setPermission = $service->permissions->create($result->id, $permissions);
getClient() is for retrieving $client. So please modify this part for your actual situation.
Note:
This answer supposes that your $client can be created the permissions to the uploaded file. Please be careful this.
$client->setDefer(true); is causing the issue. That's why it works when you create a new instance of Google client.
Another fix might be to do $client->setDefer(false); after uploading the file.
Related
I use google drive api v3 with php. I stuck with the one problem. I set pageSize to 1000, but I receive only a bit more than 300 files and nextPageToken. Why I have to use nextPageToken if I have only 400 files and set pageSize to 1000?
$drive = new Google_Service_Drive($client);
$optParams = array(
'pageSize' => 1000,
'fields' => "nextPageToken, files(id,name,mimeType,webContentLink,webViewLink)",
'q' => "'" . $folderId . "' in parents and trashed = false",
'orderBy' => 'name'
);
$results = $drive->files->listFiles($optParams);
There are various conditions that will cause the output set to be restricted to less than the proposed page size. For instance, including permissions in the files fields will limit the set to 100 each, while including parents will limit it to 360 items each. There are possibly other conditions as well.
Bottom line, you can not reliably depend on having the maximum output set at the size requested using pageSize. To insure that you get the complete set of files requested, you will need to check and process the nextPageToken.
Here is an example:
function GetFiles($service)
{
$fileFields =
'id, mimeType, name, ownedByMe, owners, parents, webContentLink';
$options =
[
'pageSize' => 1000,
'supportsAllDrives' => true,
'fields' => "files($fileFields), nextPageToken"
];
$files = [];
$pageToken = null;
do
{
try
{
if ($pageToken !== null)
{
$options['pageToken'] = $pageToken;
}
$response = $service->files->listFiles($options);
$files = array_merge($files, $response->files);
$pageToken = $response->getNextPageToken();
}
catch (Exception $exception)
{
$message = $exception->getMessage();
echo "exception: $message\r\n";
$pageToken = null;
}
} while ($pageToken !== null);
return $files;
}
The script below is creating folders within a parent folder using
"google drive API". It works perfectly however, after a while (20 folders or so) it is not working anymore.
No error message just no more folder creation within the parent folder.
It goes somewhere else!
To enable that creation a "service account" was created and parent folder is share between "personal google account" and "service account"
Can someone provide help please?
php function send_google_drive($id,$fileno,$filename1,$filename2){
global $wpdb;
require(ABSPATH.'/wp-content/themes/enemat/googledrives/vendor/autoload.php');
$client = getClient();
$service = new Google_Service_Drive($client);
if(!empty($filename1)){
$results = $service->files->listFiles();
foreach ($results->getFiles() as $item) {
if ($item['name'] == 'ENEMAT CRM FILES') {
$folderId = $item['id'];
break;
}
}
$parentid = $folderId;
$childid = "";
foreach ($results->getFiles() as $item) {
if ($item['name'] == $fileno) {
$childid = $item['id'];
break;
}
}
if(empty($childid)){
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => $fileno,
'parents'=>array($parentid),
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array(
'fields' => 'id'));
$folderId = $file->id;
}else{
$folderId = $childid;
}
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setType('anyone');
$newPermission->setRole('reader');
$service->permissions->create($folderId, $newPermission);
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => array(basename($filename1)),
'parents' => array($folderId)
));
$content = file_get_contents($filename1);
$files = $service->files->create($fileMetadata, array(
'data' => $content,
'uploadType' => 'resumable',
'fields' => 'id'));
$fileids = $files->id;
$docusignorgs = "https://drive.google.com/open?id=".$fileids."";
$folderslink = "https://drive.google.com/drive/folders/".$folderId."";
#unlink(ABSPATH."wp-content/themes/enemat/pdfs/".basename($filename1));
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setType('anyone');
$newPermission->setRole('reader');
$service->permissions->create($fileids, $newPermission);
}
if(!empty($filename2)){
$results = $service->files->listFiles();
foreach ($results->getFiles() as $item) {
if ($item['name'] == '46 - CONTRAT PARTENARIAT') {
$folderId = $item['id'];
break;
}
}
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => array(basename($filename2)),
'parents' => array($folderId)
));
$content = file_get_contents($filename2);
$files = $service->files->create($fileMetadata, array(
'data' => $content,
'uploadType' => 'resumable',
'fields' => 'id'));
$fileids1 = $files->id;
$contractdrivelink = "https://drive.google.com/open?id=".$fileids1."";
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setType('anyone');
$newPermission->setRole('reader');
$service->permissions->create($fileids1, $newPermission);
}
}
?
The reason there is no error message is because your code has no error handling! If GDrive fails to do something, it returns an error code and message to explain why. Your code should be catching that error and displaying it.
My guess is that you are hitting a rate limit. To see if this is the cause or not, add a 2 second delay between each folder creation. If it no runs correctly, you know that rate limiting is your problem.
How to share file in Google Drive API v3?I have listed of file and I want to add share functionality with Laravel?
If you mean sharing a file with another user, then you can do the following
client = new Google_Client();
// setup the client the way you do
// ....
service = new Google_Service_Drive(client)
$role = 'writer';
$userEmail = 'user#gmail.com';
$fileId = 'The ID of the file to be shared';
$userPermission = new Google_Service_Drive_Permission(array(
'type' => 'user',
'role' => $role,
'emailAddress' => $userEmail
));
$request = $service->permissions->create(
$fileId, $userPermission, array('fields' => 'id')
);
Reference:
https://developers.google.com/drive/v3/web/manage-sharing
Check my git repo for more useful examples
https://github.com/sazaamout/gDrive/blob/master/gDrive.php
I'm looking for a way to execute a little bit of JSON from my Symfony (2.6 btw) controller, moreover than an other action (post data into database)
In fact, there is an register page with a controller which put data into database and then, redirect user to another page. But i need that my controller execute too a little bit of JSON to use Mailchimp API.
I've found a lot of docs about how to render JSON response, but, it seems to me that it's not what i want to be.
There is my controller
public function registerAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isValid()) {
// Gestion du type d'utilisateur et ajout du role
$user_type = $form->get('user_profile')->get('type')->getData();
$new_role = $this->roles[$user_type];
$event = new FormEvent($form, $request);
$user = $event->getForm()->getData();
$user->addRole($new_role);
$user->getUserProfile()->setEmail($user->getEmail());
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('FOSUserBundle:Registration:register.html.twig', array(
'form' => $form->createView(),
));
}
There is my JSON request
{
"email_address": "$email",
"status": "subscribed",
"merge_fields": {
"FNAME": "$name",
"LNAME": "$lastname",
"DATE": "$date"
}
}
So, how can i do to execute this JSON with this controller ?
Thank you in advance for your help (and sorry for my excellent english)
You probably want to create the JSON from an array rather than try to pass variables. Try:
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
],
];
$json = json_encode($data);
Then I'm assuming this data gets sent to MailChimp in a POST request? If so, you could use Guzzle to send the data to MailChimp:
First add the guzzle dependency in composer by running:
composer require guzzlehttp/guzzle
Then send the data:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['body' => $data]);
To send JSON instead of raw data, do the following:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['json' => $data]);
Depending on the response status, you can then handle the logic afterwards.
You can achieve this also using JsonResponse (Symfony\Component\HttpFoundation\JsonResponse)
use Symfony\Component\HttpFoundation\JsonResponse;
...
// if you know the data to send when creating the response
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
]
];
$response = new JsonResponse($data);
return $response;
More details here https://symfony.com/doc/current/components/http_foundation.html
Have Problem with Upload any file to Google Drive Cloud via PHP,
Another Process Listing files, Children Listen, File details fork fine.
$client = new Google_Client();
$client->setApplicationName("File Upload Testing");
$client->setClientId('myID');
$client->setClientSecret('mySecret');
$client->setScopes(
array(
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive.appdata",
"https://www.googleapis.com/auth/drive.apps.readonly",
));
$parent = new Google_Service_Drive_ParentReference();
$parent->setId("0B1OLO5r_T5znT3dRTUdNNGVxdms");
$file = new Google_Service_Drive_DriveFile();
$file->setParents(array($parent));
$file->setTitle("File.png");
$file->setDescription("File pnd desc");
$file->setMimeType("image/png");
$content = file_get_contents('images/resim.jpg');
try{
$file = $service->files->insert($file, array(
'data' => $content,
'mimeType' => 'image/png',
'uploadType' => 'multipart',
'fields' => 'id'));
printf("File ID: %s\n", $file->id);
} catch( Execution $e){
echo $e->getMessage();
}
image in correct path!, wenn i remove data from array file than, upload process successfully but empty not content, with data param, return always 404 not Found!,
have couldn't found this problem, have any idea?