Can't open file created with Google Drive API - google-api

I need to create a document using Google Drive API, then give writer permission to logged in user and redirect them to created file. I'm trying to do it like this:
$credentials = storage_path('credentials.json');
$user = Socialite::driver('google')->stateless()->user();
$token = [
'access_token' => $user->token,
'refresh_token' => $user->refreshToken,
'expires_in' => $user->expiresIn
];
$client = new Google_Client();
$client->setApplicationName('Sheets');
$client->setScopes([Google_Service_Docs::DRIVE, Google_Service_Docs::DOCUMENTS]);
$client->setAccessType('offline');
$client->setAuthConfig($credentials);
$client->setAccessToken($token);
$service = new Google_Service_Docs($client);
$serviceDrive = new Google_Service_Drive($client);
$body = new Google_Service_Drive_DriveFile(array(
"name" => 'Testing ' . Lang::get('pls.export.name')
));
$doc = $serviceDrive->files->create($body);
$permission = $this->insertPermission($serviceDrive, $doc->id, $user->email, 'user', 'writer');
$url = "https://docs.google.com/document/d/" . $doc->id . "/edit#";
return Redirect::away($url);
This is the insertPermission function
function insertPermission($service, $fileId, $value, $type, $role)
{
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setEmailAddress($value);
$newPermission->setType($type);
$newPermission->setRole($role);
if ($role == 'owner') {
$permission = $service->permissions->create($fileId, $newPermission, array('fields' => 'id', 'transferOwnership' => 'true'));
} else {
$permission = $service->permissions->create($fileId, $newPermission);
}
if ($permission) {
return $permission;
}
return NULL;
}
After I run this code, I can see that the file was indeed created (I can get its id too), I also receive a notification on email that the file was shared with me, but I can't open the file itself. I'm getting a notification that page does not exist and "Sorry, unable to open the file at this time".
P.S. The same approach works perfectly fine when I'm creating a spreadsheet, instead of document. I can access the spreadsheet without any issues afterwards

After some research and testing I managed to fix the issue. The problem was I was using google drive api to create the file. Instead, I used Google Docs API like so:
$document = new Google_Service_Docs_Document(array(
'title' => 'Testing ' . Lang::get('pls.export.name')
));
$document = $service->documents->create($document);
Everything worked like a charm

Related

Laravel 7 HTTP client attach multiple files

I am trying to make POST to a rest API where I need to send multiple files from a user input form. I have managed to get it to work with a single file, but when there are multiple files sent as an array ($file[]), I can't see anything in the laravel docs to show how this can be done.
$response = 'API_URL';
$response = Http::withToken(ENV('API_KEY'))
->attach('file', fopen($request->file, 'r'))
->post($url, [
'uuid' => $request->uuid,
]);
You can do it by:
->attach('file[0]', fopen($request->file[0], 'r'))
->attach('file[1]', fopen($request->file[1], 'r'))
if your $files is an array of files that wants to send, you can do like below:
$response = Http::withToken(ENV('API_KEY'));
foreach($files as $k => $file)
{
$response = $response->attach('file['.$k.']', $file);
}
$response = $response->post($url, [
'uuid' => $request->uuid,
]);
Attach multiple files if the file name also unknown, together with request data in one request, if request has file or does not have file. with authorization header
if ($method == 'POST') {
// Attached multiple file with the request data
$response = Http::withHeaders($headers);
if($request->files) {
foreach ($request->files as $key=> $file) {
if ($request->hasFile($key)) {
// get Illuminate\Http\UploadedFile instance
$image = $request->file($key);
$fileName = $request->file($key)->getClientOriginalName();
$response = $response->attach($key, $image->get(),$fileName);
}
}
$response = $response->post($this->$requestUrl, $request->all());
} else {
$response = Http::withHeaders($headers)->post($this->webApiBaseUri, $request->all());
}
}

update data to database laragon using api

I want to update data to the database in ionic. how to make the data update. Here what I tried. I try using postmen to post the api and it appear success but the data does not change.
in api.php
public function update (Request $request)
{
$id = $request->id;
$medname = $request->medname;
$price = $request->price;
$stock = $request->stock;
$medno = $request->medno;
$ingredient = $request->ingredient;
$description = $request->description;
$addinfo = $request->addinfo;
AddMedicine:: where('medname',$medname)->update([
'id' =>$id,
'medname'=>$medname,
'price'=>$price,
'stock'=>$stock,
'medno'=>$medno,
'ingredient'=>$ingredient,
'description'=>$description,
'addinfo'=>$addinfo,
]);
$msg = "Data Updated";
$datamsg = response()->json([
'success' => $msg
]);
return $datamsg->content();
}
route
Route::put('/update','ApiController#update');
Are you sure use PUT request ? Because need to CSRF token please inspect
https://stackoverflow.com/questions/30756682/laravel-x-csrf-token-mismatch-with-postman

Laravel and DropzoneJS file uploaded with different extension

I created a form here with Laravel and DropzoneJS and I tried uploading a Gimp file (.xcf) and when it is uploaded it is saved in S3 as the following
<random-name>.
without the "xcf" extension just random name ending with a dot.
Also, I created a text file and renamed it to test.xcf when I tried uploading that file it was uploaded with the .txt extension.
Here is my UploadController.php which handles the upload:
<?php
namespace App\Http\Controllers;
use App\Upload;
use Illuminate\Http\Request;
class UploadController extends Controller
{
public function upload(Request $request)
{
$originalName = $request->file('file')->getClientOriginalName();
$fileSize = $request->file('file')->getClientSize();
$path = $request->file('file')->store('documents');
$explode = explode('documents/', $path);
$name = $explode[1];
$uniqueId = $this->generateUniqueId();
$upload = new Upload();
$upload->unique_id = $uniqueId;
$upload->name = $name;
$upload->path = $path;
$upload->original_name = $originalName;
$upload->size = $fileSize;
if ($upload->save())
{
return response()->json([
'original_name' => $originalName,
'size' => $fileSize,
'url' => env('AWS_URL') . $path,
'id' => $uniqueId,
'status' => 'OK'
]);
}
return response()->json(['status' => 'BAD', 'message' => 'There was a problem saving your file.']);
}
public function generateUniqueId()
{
$result = '1';
$result .= rand(100000000, 999999999);
while(Upload::where('unique_id', '=', $result)->first())
{
$result = '1';
$result .= rand(100000000, 999999999);
}
return $result;
}
}
I've got no idea why it's doing that.
I suggest, you generate your own hash for filename, like I do in this code:
$file = $request->file('csv');
$path = $file->storeAs(
'csv',
md5($file->getClientOriginalName()) . $file->getClientOriginalExtension(),
's3'
);
You can also add uniqid() to md5 input
If you're using laravel 5+ then you should get the extension also using this.
$extension = $file->getClientOriginalExtension();
This will work fine.

Test case removing original file while uploading a file through test case

This is my test case
public function testSelfieFileUpload()
{
$path = public_path().'/uploads/sample1.jpg';
$name = 'sample1.jpg';
$file = new UploadedFile($path, $name, 'image/png', filesize($path), null, true);
$response = $this->post($this->endpoint, ['file' => $file], $this->setHeaders());
$response->assertStatus(200)
->assertJsonFragment(array("status" => "success"));
}
But the problem is that it is deleting the original file from the folder i.e sample1.jpg
Help me out. Am i missing something here? Although the test case is running fine.
When having the same problem, after looking in the source code, I couldn't find a flag that fixes it.
As I workaround, I created a copy when running the test, which gets deleted but it's no longer a problem.
$temporaryFilePath = $this->createTempFile($this->testFilePath);
$file = new \Illuminate\Http\UploadedFile($path, $name, $mime, filesize($path), null, true);
//do your test logic
...
private function createTempFile($path) {
$tempFilePath = $this->basePath . 'temp.xlsx';
copy($path, $tempFilePath);
return $tempFilePath;
}
You might want to refine this depending on your needs.
This works for me.
You have to store in both public_path and storage_path the same file:
$filename = storage_path('app/pdfstest/COVID 19.pdf');
$pdf = new UploadedFile($filename, $name, 'application/pdf');
$response = $this->post('/gallery', [
'user_id' => $this->user->id,
'doc' => [$pdf],
'from_tab' => 'test'
]);
$temp_pdf = file_get_contents(public_path('pdfstest/COVID 19.pdf'));
Storage::put('pdfstest/COVID 19.pdf', $temp_pdf);

Incorrect Signature in facebook stream_publish call

I am having a facebook error on stream_publish call. I actually used an extension for Magento for Fconnect. Fconnect & Flogin is working fine. But it is requirement that when user place an order it should be posted on user's wall. For that I have implemented like this
document.observe('click', function(e){
if (e.element().match('a[rel^=facebook-connect]') || e.element().match('button[rel^=facebook-connect]')) {
e.stop();
FB.login(function(response){
if(response.status=='connected') setLocation('http://staging.mystore.com/facebook/customer_account/connect/');
}, {perms:"email,publish_stream"});
}
});
in Facebook Client file generateSignature method is like this
private function _generateSig($params_array)
{
Mage::log($params_array);
$str = '';
ksort($params_array);
foreach ($params_array as $k=>$v) {
$str .= "$k=$v";
}
$str .= $this->_secret;
Mage::log($str);
Mage::log('md5 sigs:: ' . md5($str));
return md5($str);
}
& My code that is calling the API is like this
$message = 'just placed an order on mystore.com';
$attachment = array(
'name' => "mystore",
'href' => 'http://www.mystore.com/',
'description' => 'New order on mystore.com',
'media' => array(array('type' => 'image',
'src' => 'http://www.mystore.com/skin/frontend/default/mystore/images/logo.png',
'href' => 'http://www.mystore.com/')));
$action_links = array( array('text' => 'Buy#mystore', 'href' => 'http://www.mystore.com/'));
$attachment = json_encode($attachment);
$action_links = json_encode($action_links);
try{
// if( $facebook->api_client->stream_publish($message, $attachment, $action_links, null, $target_id))
if($this->_getClient()->call( 'facebook.stream.publish',
array($message, $attachment, $action_links,
$this->_getClient()->users->getLoggedInUser(),
Mage::getSingleton('facebook/config')->getApiKey() )
) )
{
Mage::log( "Added on FB Wall" );
}
} catch(Exception $e)
{
Mage::log( "Exception in wall write" );
Mage::log($e);
}
After logging the Signature I found in log is
api_key=XXXXXXXXmethod=facebook.stream.publishsession_key=2.AQCm5fABfobInAS5.3600.1309352400.1-1000025660978090=just placed an order on mystore.comcall_id=1309345883.3068format=JSONv=1.01={"name":"mystore","href":"http:\/\/www.mystore.com\/","description":"New order on mystore.com","media":[{"type":"image","src":"http:\/\/www.mystore.com\/skin\/frontend\/default\/mystore\/images\/logo.png","href":"http:\/\/www.mystore.com\/"}]}2=[{"text":"Buy#mystore","href":"http:\/\/www.mystore.com\/"}]3=1000025660978094=5070afefb42b162aff748f55ecf44d110d9e2a90117ee1704e2adb41f1d190fa
I have never done any development on Facebook SO I have no Idea what to do? Please help me with solution. & let me know if u guys need any other info to understand this.
Oh yeah One more thing the Client File code that is calling Api (call method) its like this
private function _prepareParams($method, $params)
{
$defaultParams = array(
'api_key' => $this->_apiKey,
'call_id' => microtime(true),
'format' => 'JSON',
'v' => '1.0'
);
if($this->_sessionKey){
$defaultParams['session_key'] = $this->_sessionKey;
}
$params = array_merge($defaultParams, $params);
foreach ($params as $key => &$val) {
if (!is_array($val)) continue;
$val = Zend_Json::encode($val);
}
$params['method'] = $method;
if(isset($params['sig'])) {
unset($params['sig']);
}
$params['sig'] = $this->_generateSig($params);
return $params;
}
public function call($method, $args=array())
{
Mage::log($args);
$params = $this->_prepareParams($method, $args);
$client = self::_getHttpClient()
->setUri(self::FACEBOOK_REST_URI)
->setMethod(Zend_Http_Client::POST)
->resetParameters()
->setParameterPost($params);
try {
$response = $client->request();
} catch(Exception $e) {
throw new Mage_Core_Exception('Service unavaliable');
}
if(!$response->isSuccessful()) {
throw new Mage_Core_Exception('Service unavaliable');
}
$result = Zend_Json::decode($response->getBody());
//json decode returns float on long uid number? is_json check? old php?
if(is_float($result)){
$result = $response->getBody();
}
if(is_array($result) && isset($result['error_code'])) {
throw new Mage_Core_Exception($result['error_msg'], $result['error_code']);
}
return $result;
}
For calling API I used two ways $this->_getClient()->call( 'facebook.stream.publish',
& $this->_getClient()->call( 'stream_publish',
None of them are working
ok GUys I figure out the mistake
look at my code
format=JSONv=1.01={"name":"mystore","href":"http:\/\/www.mystore.com\/","description":"New order on mystore.com","media":[{"type":"image","src":"http:\/\/www.mystore.com\/skin\/frontend\/default\/mystore\/images\/logo.png","href":"http:\/\/www.mystore.com\/"}]}2=[{"text":"Buy#mystore","href":"http:\/\/www.mystore.com\/"}]3=1000025660978094=5070afefb42b162aff748f55ecf44d110d9e2a90117ee1704e2adb41f1d190fa
where u can see format=JSONv=1.01={....}2=[{.....}] the problem was I used numeric arrays for parameters. they should be associated arrays
like message={new order}attachment={....}
Once I fixed the associative array problem my code start working correctly
here is a link that'll give u detail about parameters to pass to stream.publish
http://schoolout.net/en/developers/view/39
Hope this will help somebody else too.

Resources