How to update file in google drive v3 PHP - php

I cant seem to update file in google drive with the following code, everything goes fine but file remains untouched? I am working with v3 api.
function updateFile($service, $fileId, $data) {
try {
$emptyFile = new Google_Service_Drive_DriveFile();
$file = $service->files->get($fileId);
$service->files->update($fileId, $emptyFile, array(
'data' => $data,
'mimeType' => 'text/csv',
'uploadType' => 'multipart'
));
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}

I managed to do it, you have to put empty file as second argument, not sure why but this post helped me a lot: Google Drive API v3 Migration
This is final solution:
function updateFile($service, $fileId, $data) {
try {
$emptyFile = new Google_Service_Drive_DriveFile();
$service->files->update($fileId, $emptyFile, array(
'data' => $data,
'mimeType' => 'text/csv',
'uploadType' => 'multipart'
));
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
where $fileId is file you are updating, and data is new content you are updating your file.
Dont forget to refresh google drive after this because it's preview doesnt change and I lost one hour on that :/. Hope this helps.

function updateFile($fileId,$newDescription){
try {
// First retrieve the file from the API.
$emptyFile = new Google_Service_Drive_DriveFile();
// File's new metadata.
$emptyFile->setDescription($newDescription);
// Send the request to the API.
$driveService->files->update($fileId, $emptyFile, array());
print 'success';
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}//end update
The method is essential if you wish to update staff like desciption. I copied the idea from v2.
// File's new metadata.
$file->setTitle($newTitle);
$file->setDescription($newDescription);
$file->setMimeType($newMimeType);
NB: Also you have to ensure 3 parameter of update function is an array
Also as stated in other helpful answer; Ensure you refresh google drive to check

Related

aws-sdk 3 putobject not retrieving the file data PHP

I am trying to read the data from a txt file on my amazon AWS bucket. But the body key in the response array is shown as NULL. My code -
function s3_file_get_contents($path, $private = TRUE, $bucket = '') {
require_once(CODE_BASE_DIR . '/ds_engine/docSuggest/external/aws-sdk-3/aws-autoloader.php');
try {
$s3Client = new Aws\S3\S3Client(array('region' => S3_ENDPOINT_REGION, 'version' => S3_ENDPOINT_VERSION,
'credentials' => array(
'key' => S3_SUGGESTADOC_API_KEY,
'secret' => S3_SUGGESTADOC_API_SECRET,
),
));
$result = $s3Client->getObject(array(
'Bucket' => $private ? S3_BUCKET_DOCSUGGEST : S3_BUCKET_SUGGESTADOC,
'Key' => $path,
));
} catch (Exception $e) {
$error = $e->getMessage();
log_message('ERROR', '['.__FUNCTION__.'] Exception: '.$error);
}
die(print_array($result['body']));
return $error ? $error : $result['body'];
}
The file contains some text but nothing is displayed in the console. Rest assured, I have setup the connection properly and there is no issues in that. I am able to download the file but just not read from it.
P.S - The response metadata has an object URL. Using that the file can be downloaded. So I guess I am hitting the correct path but still no success.
The data is in $result['Body'], not in $result['body'].
Look at the documentation:
http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html#downloading-objects
Use var_dump($result) to understand better than structure of the response.

Exception trying to post a link on Facebook page using grahp API for PHP

I've already searched among the other questions here on Stackoverflow and on other websites, but I couldn't find a solution, also because it seems that FB often changes the authentication method, so old solutions are no more valid.
I'm using SDK4 and this is my code as I have it at the moment
FacebookSession::setDefaultApplication($app_id, $app_secret);
$session = FacebookSession::newAppSession();
try {
$session->validate();
} catch (FacebookRequestException $ex) {
echo $ex->getMessage();
} catch (\Exception $ex) {
echo $ex->getMessage();
}
if($session)
{
try {
$response = (new FacebookRequest(
$session, 'POST', '/me/feed', array(
'link' => 'www.mysite.it',
'message' => 'some text'
)
))->execute()->getGraphObject();
echo "Posted with id: " . $response->getProperty('id');
} catch(FacebookRequestException $e) {
echo "Exception occured, code: " . $e->getCode() .
" with message: " . $e->getMessage();
}
}
I get this message:
"Exception occured, code: 2500 with message: An active access token must be used to query information about the current user."
Given the message, the session is correctly created and validated, the problem is on the execute() method, how do I fix it?
It looks like you've created your session for your app, but to post on a users behalf you need to get an access token for said user and then call
$this->facebook = new FacebookSession($access_token);

How can I make Symfony2 ignore Guzzle Client bad response exception in my custom controller?

function order_confirmationAction($order,$token) {
$client = new \GuzzleHttp\Client();
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
If $client->post() response status code is an "Error 500" Symfony stops the script execution and throw new exception before the json decoding.
How can I force Symfony to ignore $client->post() bad response and execute till the last if statement?
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $serialized_order)
);
}
catch (\GuzzleHttp\Exception\ServerException $e) {
if ($e->hasResponse()) {
$m = $e->getResponse()->json();
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $m['result']['message']);
}
}
I solved like this. In that way I can access to responses of remote server even if it returns an error 500 code.
Per Guzzle documentation:
Guzzle throws exceptions for errors that occur during a transfer.
Specifically, if the API responds with a 500 HTTP error, you shouldn't expect its content to be JSON, and you don't want to parse it, so you're better off re-throwing an exception from there already (or informing the user that something went wrong). I would suggest trying this out:
function order_confirmationAction($order, $token) {
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
}
catch (Exception $e) {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $e->getMessage());
}
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
}
It is probably also a good idea to check for errors when JSON-decoding the response, because there could be surprises in the content you're getting (eg. wrong format, missing or unexpected fields or values, etc.).

Copy remote file using Guzzle

I'm trying to copy a remote file (image PNG, GIF, JPG ...) to my server. I use Guzzle since I sometimes get 404 with copy() even if the file exists and I also need to do a basic auth. This script is within a long script launched in command triggered by a cron job.
I'm pretty new to Guzzle and I successfully copy the image but my files have wrong mime type. I must be doing something wrong here. Please suggest me a good way to do this (including checking success/failure of copy and mime type check). If file has no mime type I would pop an error with details informations.
Here is the code:
$remoteFilePath = 'http://example.com/path/to/file.jpg';
$localFilePath = '/home/www/path/to/file.jpg';
try {
$client = new Guzzle\Http\Client();
$response = $client->send($client->get($remoteFilePath)->setAuth('login', 'password'));
if ($response->getBody()->isReadable()) {
if ($response->getStatusCode()==200) {
// is this the proper way to retrieve mime type?
//$mime = array_shift(array_values($response->getHeaders()->get('Content-Type')));
file_put_contents ($localFilePath , $response->getBody()->getStream());
return true;
}
}
} catch (Exception $e) {
return $e->getMessage();
}
When I do this my mime type is set to application/x-empty
Also it looks like when status is different from 200 Guzzle will automatically throw an exception. How can I stop this behaviour and check status myself so I can custom error message?
EDIT: This was for Guzzle 3.X
Now this is how you can do it using Guzzle v 4.X (works as well with Guzzle 6)
$client = new \GuzzleHttp\Client();
$client->get(
'http://path.to/remote.file',
[
'headers' => ['key'=>'value'],
'query' => ['param'=>'value'],
'auth' => ['username', 'password'],
'save_to' => '/path/to/local.file',
]);
Or using Guzzle stream:
use GuzzleHttp\Stream;
$original = Stream\create(fopen('https://path.to/remote.file', 'r'));
$local = Stream\create(fopen('/path/to/local.file', 'w'));
$local->write($original->getContents());
This looks great. Is there better/proper solution when using Guzzle 4?
Your code can be simplified a great deal. My example code below will stream the body of the response directly to the filesystem.
<?php
function copyRemote($fromUrl, $toFile) {
try {
$client = new Guzzle\Http\Client();
$response = $client->get($fromUrl)
->setAuth('login', 'password') // in case your resource is under protection
->setResponseBody($toFile)
->send();
return true;
} catch (Exception $e) {
// Log the error or something
return false;
}
}
When I do this my mime type is set to application/x-empty
A filesystem mimetype?
Also it looks like when status is different from 200 Guzzle will automatically throw an exception. How can I stop this behaviour and check status myself so I can custom error message?
Guzzle will throw an exception for bad responses like 4xx and 5xx. No need to disable this. Just catch an exception and deal with the error there.
Look at this with post:
$myFile = fopen('path/to/file', 'w') or die('Problems');
$client = new \Guzzle\Service\Client();
$request = $client->post('https://www.yourdocumentpage.com', array(), ['pagePostField' => 'data'], ['save_to' => $myFile]);
$client->send($request);
fclose($myFile);
here you must send the request of your "post"
and with get
$myFile = fopen('path/to/file', 'w') or die('Problems');
$client = new \GuzzleHttp\Client();
$request = $client->get('https://www.yourdocumentpage.com', ['save_to' => $myFile]);
and here you don't need to send the request,
and here you'll find a lot of documentation, you must have guzzle 6 for doing that, and if you are using GOUTTE at the same time you'll need goutte 3.1, update your require in your composer.json
using Guzzle 6 just use SINK option. see below detailed function
Extra:
use GuzzleHttp\Client; Guzzle namespace included
$access_token = if you need auth else simply remove this option
ReportFileDownloadException = custom exception
/**
* download report file and read data to database
* #param remote url
* #return N/A
* #throws ReportFileDownloadException
*/
protected function getReportFile($report_file_url)
{
$file = $this->tempDirectory . "/" . basename($report_file_url);
$fileHandle = fopen($file, "w+");
try {
$client = new Client();
$response = $client->get($report_file_url, [
RequestOptions::SINK => $fileHandle,
RequestOptions::HEADERS => [
"Authorization" => "Bearer $access_token"
]
]);
} catch (RequestException $e) {
throw new ReportFileDownloadException(
"Can't download report file $report_file_url"
);
} finally {
#fclose($fileHandle);
}
throw new ReportFileDownloadException(
"Can't download report file $report_file_url"
);
}

Create a Google Drive Spreadsheet from a local CSV file via the Google Drive API

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.

Categories