Importing generated csv from Laravel into Google Sheets - laravel

I'm trying to import an automatically generated csv into Google Sheets using this as cell value:
=importData("https://example.com/reports/some-report")
When I try importData on a static file on the server everything works as expected (like =importData("https://example.com/storage/some-static-report.csv") )
..but when I generate the file on the fly () I get a #N/A in the cell; "Resource at url not found." error.
This is the Laravel code to generate the csv:
public function downloadReportsAsCSV(Request $request) {
$list = [];
$list[] = ['timestamp', 'id', 'value'];
// ... fill the list with data here
$callback = function() use ($list) {
$out = fopen('php://output', 'w+');
// Write CSV lines
foreach ($list as $line) {
fputcsv($out, $line);
}
fclose($out);
};
$name = 'somereport.csv';
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename='. $name,
];
return response()->stream($callback, 200, $headers);
}
The route to this method is public so authentication is not a problem in this case.
When I call https://example.com/reports/some-report in a browser it downloads the file (as somereport.csv), but somehow Google Sheeds can't handle it the way I expect it to.
Any ideas on how to make this work?

It seems to be working after all, it's just that Google Sheets apparently needed quit some time before updating the field (at least a couple of minutes).
If anyone has any idea how to trigger Google Sheets to update the data immediately I'd sure like to know.

Related

How to upload multiple images with base64 in laravel & vue-js

I have been trying to upload multiple images with base64 but it uploads only the second one.
and Is there any easy way to upload images in larvel-vueJS instead of base 64.
this is the Vue-js method:
updateIMG(e){
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
if(file['size'] < 9111775){
reader.onloadend = (file) => {
this.landingform.logo = reader.result;
this.landingform.landingBg = reader.result;
}
reader.readAsDataURL(file)
}else {
swal.fire({
icon: 'error',
title: 'Oops...',
text: 'You are uploading a large fiel!',
footer: 'You are authorized to upload files less than 10MB.'
})
}
the method called like this:
<input type="file" #change="updateIMG" name="logo" class="form-input">
and this is my controller:
public function updateLanding(Request $request)
{
$landnginIMG = LandingImage::whereIn('id', [1]);
if ($request->logo){
$name = time().'.' . explode('/', explode(':', substr($request->logo, 0,
strpos($request->logo, ';')))[1])[1];
\Image::make($request->logo)->save(public_path('img/landing/').$name);
$request->merge(['logo' => $name]);
};
if ($request->landingBg){
$bgname = time().'.' . explode('/', explode(':', substr($request->landingBg, 0,
strpos($request->landingBg, ';')))[1])[1];
\Image::make($request->landingBg)->save(public_path('img/landing/').$bgname);
$request->merge(['landingBg' => $bgname]);
};
$landnginIMG->update([
'logo'=> $request ['logo'],
'landingBg'=> $request ['landingBg'],
]);
return ['message' => 'all is done'];
}
There are a few factors your must follow.
First
Your form should let you select multiple files
Second
Your JavaScript must handle all of those files when selected. Check this line of your code.
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
e.target.files[0] is taking the first file. You should loop and go through all files.
let files = e.target.files;
Now, use JavaScript foreach loop and convert each file to base64 and store them on array. Then, send that array to sever.
On the server, do the same. You will receive an array so you should loop through each and convert it back to image and save it.
Thanks.
Pls check if this helps:
Vuejs example of multiple image upload https://picupload.netlify.app/
VueJS code repo https://github.com/manojkmishra/dw_take5
Concerned File- https://github.com/manojkmishra/dw_take5/blob/master/src/components/ImageUploader.vue
PHP[Laravel] part is behind firewall so upload submission will not work outside intranet. Here is the controller function code
public function imagesupload(Request $request){
if (count($request->images)) {
foreach ($request->images as $image) {
$image->store('images');
}
}
return response()->json(["message" => "Done"]);
}

problem with multiple HTTP requests in Laravel with Guzzle

I'm using Guzzle version 6.3.3. I want to make multiple HTTP requests from an external API. The code shown below worker perfect for me. This is just one single request.
public function getAllTeams()
{
$client = new Client();
$uri = 'https://api.football-data.org/v2/competitions/2003/teams';
$header = ['headers' => ['X-Auth-Token' => 'MyKey']];
$res = $client->get($uri, $header);
$data = json_decode($res->getBody()->getContents(), true);
return $data['teams'];
}
But now I want to make multiple requests at once. In the documentation of Guzzle I found out how to do it, but it still didn't work properly. This is the code I try to use.
$header = ['headers' => ['X-Auth-Token' => 'MyKey']];
$client = new Client(['debug' => true]);
$res = $client->send(array(
$client->get('https://api.football-data.org/v2/teams/666', $header),
$client->get('https://api.football-data.org/v2/teams/1920', $header),
$client->get('https://api.football-data.org/v2/teams/6806', $header)
));
$data = json_decode($res->getBody()->getContents(), true);
return $data;
I get the error:
Argument 1 passed to GuzzleHttp\Client::send() must implement interface Psr\Http\Message\RequestInterface, array given called in TeamsController.
If I remove the $header after each URI then I get this error:
resulted in a '403 Forbidden' response: {"message": "The resource you are looking for is restricted. Please pass a valid API token and check your subscription fo (truncated...)
I tried several ways to set X-Auth-Token with my API key. But I still get errors and I don't know many other ways with Guzzle to set them.
I hope someone can help me out :)
Guzzle 6 uses a different approach to Guzzle 3, so you should use something like:
use function GuzzleHttp\Promise\all;
$header = ['headers' => ['X-Auth-Token' => 'MyKey']];
$client = new Client(['debug' => true]);
$responses = all([
$client->getAsync('https://api.football-data.org/v2/teams/666', $header),
$client->getAsync('https://api.football-data.org/v2/teams/1920', $header),
$client->getAsync('https://api.football-data.org/v2/teams/6806', $header)
])->wait();
$data = [];
foreach ($responses as $i => $res) {
$data[$i] = json_decode($res->getBody()->getContents(), true);
}
return $data;
Take a look at different questions on the same topic (#1, #2) to see more usage examples.

How can I pass image file from Laravel to Express using Graphql?

I have a laravel project and my goal is to pass an image file from laravel to my express project, so that my graphql can save the name of my image file after
successfully renaming the image and uploading it in my express project.
At the moment, I am using \Softonic\GraphQL to query data from my express project. Example:
public function getUsers()
{
$client = \Softonic\GraphQL\ClientBuilder::build('http://localhost:3002/graphql');
$query = '
query GetUsers($sort:[[String!]!]!){
users(perPage:10, page: 1, sort: $sort){
users{
email
}
}
}
';
$var = [
'sort' => "email"
];
$response = $client->query($query, $var);
return $response->getData();
}
How should i implement it when uploading an image ? my current code looks like this ..
public function updateImg(Request $request)
{
$client = \Softonic\GraphQL\ClientBuilder::build('http://localhost:3002/graphql');
$query = '
mutation updateImage(id:ID!, $image: Upload!){
updateImage(id:1, image: $image){
users{
email
}
}
}
';
$var = [
'image' => $request->file('uploadImg');
];
$response = $client->query($query, $var);
return $response->getData();
}
On my express, when i inspect my image in console.log(), it returns empty.
I am not sure if the way im doing is correct or if it is even achievable.
One way to add support for uploading files to GraphQL is to add multipart form request support through this specification by Jayden Seric. He also provides an implementation project for certain environments. However, I have only tried and tested this with apollo-client and apollo-server-express.

deleteFileAfterSend Laravel response doesn't delete file in tests

I an have laravel 5.5 App.
I'm trying to make a test for download PDF with laravel snappy.
So far I have in my CheckTest.php one function:
public function testPrintCheck(){
$check = $this->createCheck();
$route ="/api/checks/print/$check->id";
$response = $this->get($route);
$this->assertEquals($response->headers->get('content-type') , 'application/pdf');
$response->assertStatus(200);
}
In my controller I have:
public function printCheck(Request $request, Check $check){
$pdf = \PDF::loadView("pdf.check");
$file= storage_path(). "/app/checks/$check->id.pdf";
$pdf->save($file);
$headers = array(
'Content-Type: application/pdf'
);
return response()->download($file, "check_n_$check->id.pdf", $headers)->deleteFileAfterSend(true)->setStatusCode(200);
}
The current test works but I expect to delete file that I have create after download (with deleteFileAfterSend(true)) , but the file is not deleted.
So if I add the assert that file not exist it fails.
There is a possible solution to this according to the issue created not so long ago on github:
https://github.com/laravel/framework/issues/36286
Working on Laravel 8.24
Basically we need to force sending file contents, which then triggers file deletion
public function test(): void
{
$response = $this->get('url/to/download');
// Here the file is not deleted yet
$response->sendContent();
// Here the file is deleted
}

Image validation not working If using ajaxForm

I tried googling and saw other questions posted at this forum but could not find any solution for my issue. I am using Jquery ajaxForm method to submit form. My form contains one file field too in the form that can be used to upload a picture. I have defined the validation in my model. But the issue is even i am uploading a correct jpg file, still i am getting error message that
Argument 1 passed to Illuminate\\Validation\\Factory::make() must be of the type array, object given.
Javascript Code
$('#create_form').ajaxForm({
dataType:'JSON',
success: function(response){
alert(response);
}
}).submit();
Controllder Code
if ($file = Input::file('picture')) {
$validator = Validator::make($file, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
}
Model Code
public static $file_rules = array(
'picture' => 'required|max:2048|mimes:jpeg,jpg,bmp,png,gif'
);
POST Request
I know that my validation defined in the model expects an array. But by passing $file in the validator, an object is passed. Then i changed the code like:
$validator = Validator::make(array('picture' => $file->getClientOriginalName()), User::$file_rules);
Now i am getting error:
The picture must be a file of type: jpg, JPEG, png,gif.
The problem is you pass file object directly to validate. Validator::make() method takes all four parameters as array. Moreover, you need to pass the whole file object as value so that Validator can validate mime type, size, etc. That's why your code should be like that.
$input = array('picture' => Input::file('picture'));
$validator = Validator::make($input, User::$file_rules);
if ($validator->fails()) {
$messages = $validator->messages();
foreach ($messages->all(':message') as $message) {
echo $message; exit;
}
return Response::json(array('message'=>$response, 'status'=>'failure'));
} else {
// do rest
}
Hope it will be useful for you.
Try rule like this.
$rules = array(
'picture' => 'image|mimes:jpeg,jpg,bmp,png,gif'
);
or try removing 'mimes'

Resources