CSV export in php - csv row as a variable - laravel

I want to export a data into CSV file using PHP Laravel.
I used every row as a variable and add to csv at last. It helps me to create custom CSV file collumn header, so I must follow this rule.
What I have done is this-
$tweets = DB::select(DB::raw($query));
foreach ($tweets as $row)
{
$row = get_object_vars($row);
// iterate over each tweet and add it to the csv
$output .= implode(",",
array(
$row['completion_date'],
$row['site_id'],
$row['country'],
$row['state'],
$row['city'],
$row['active_ipp'],
$row['description_of_project'],
$row['total_excess_furniture']
)
); // append each row
$output .="\n"; //Adding New Line
}
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment;filename="'.Carbon\Carbon::now()->toDateTimeString().'.csv"',
);
return Response::make(rtrim($output, "\n"), 200, $headers);
It is working with some errors.
The errors are, when there is a comma in the object string, it does not work perfectly.
So, I can't use implode I think.
Is there any other solution for adding CSV row as a variable like this?

You can try something along the lines of:
$items = [
[
'field1' => 'string with " quotes',
'field2' => 'string without commas',
],
[
'field1' => 'string without quotes',
'field2' => 'string, with, commas',
],
];
ob_start();
$buffer = fopen('php://output', 'w+');
foreach($items as $item) {
fputcsv($buffer, [
$item['field1'],
$item['field2'],
]);
}
$output = ob_get_clean();
fputcsv will deal with commas or quotes in your variables. Instead of writing the output to a file, you can send the output to a buffer and store it to a variable using ob_start and ob_get_clean.

Related

Generating and downloading a text file on the fly in Laravel

My data is stored in the database and I need to give it out of it in a text file. There is no point in creating a file on disk, but an attempt to generate a response with a file does not work. Found a way like this but it doesn't work ERR_INVALID_RESPONSE
$contents = 'My data from db';
$filename = 'example.txt';
return response()->streamDownload(function () use ($contents) {
echo $contents;
}, $filename);
In your route name the route with something reasonable like:
Route::get('filename.txt', [FooController::class, 'foo']);
And in your controller at foo() action:
$headers = [
'Content-Type' => 'application/plain',
'Content-Description' => 'File name',
];
$contents = 'My data from db';
return \Response::make($contents, 200, $headers);

Path of the file stored in s3 does not match with provided - Using Laravel

I'm building a service to upload images with laravel and stored in a aws s3 bucket, this is the function responsible for store image.
public function fromUrl(Request $request)
{
$validator = Validator::make($request->all(), [
'files' => 'required|array|min:1',
'files.*' => 'string',
]);
if (!$validator->fails()) {
$paths = [];
foreach ($validator->validate()['files'] as $file) {
$url = config('services.s3.host') . Storage::disk('s3')->put('images/public', file_get_contents($file), 'public');
array_push($paths, $url);
}
return $paths;
} else {
throw new ValidateException([
'message' => $validator->errors()->toArray(),
'rules' => $validator->failed()
]);
}
}
The request body looks like this.
{
"files": [
"https://image-url-1",
"https://image-url-2"
]
}
I expect that the path returned when saving the image is something like this.
[
"https://my-bucket-url/images/public/random-name-for-image1",
"https://my-bucket-url/images/public/random-name-for-image2"
]
but instead I'm getting the following.
[
"https://my-bucket-url/1",
"https://my-bucket-url/1"
]
You are misusing put in your example.
Firstly the first parameter is the path plus filename and you have no filename random logic. The third parameter is options array.
$randomFileName = uniqid(rand(), true);
$path = 'images/public/' . $randomFileName;
Storage::disk('s3')->put($path, file_get_contents($file));
This code will save an element at images/public/$randomFileName. To return the proper path you can use the url() method.
$url = Storage::disk('s3')->url($path);
array_push($paths, $url);

Import CSV Using Laravel Excel (Maat)

Hi I have an excel file with the details of passengers under the trip ID. I want to import that excel file in my table. please see the picture below:
the first row with the blue color is my column names on my table. my problem is how can I save the value of D2:G2 in next_of_kin table with this kind of format.
[
{"name":James Lara,"mobile":12345678},
{"name":Jasmine Lara,"mobile":12345678}
]
this is my code on my controller.
// Get excel file
$path = $request->file;
// Save the content to passenger
Excel::load($path, function ($reader) use ($request) {
$trip = Trip::where('id', $request->trip_customer_id)->first();
foreach ($reader->toArray() as $row) {
$trip->passengers()->create($row);
}
});
on my foreach inside the controller this looks like.
foreach ($reader->toArray() as $row) {
$given_name = array(
['name' =>$row['nok_one'],'mobile' => $row['nok_one_mobile']],
['name' =>$row['nok_two'],'mobile' => $row['nok_two_mobile']]
);
$trip->passengers()->create([
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'next_of_kin' => $given_name
]);
}

Codeigniter - two upload fields in one form

I'm trying to upload an image and an mp3 in Codeigniter, from a form with two file input fields. The image field is called userfile, the mp3 field is called trackfile.
In my model I have this code (modified):
$image_resource = $this->library_model->upload_image($_FILES);
$data = array(
'name' => $this->input->post('name'),
'imageresource' => $image_resource
);
$this->db->insert('table_name',$data);
$insert_id = $this->db->insert_id();
if ($_FILES && $_FILES['trackfile']['name'] !== "") {
$config = array(
'allowed_types' => 'mp3',
'upload_path' => './assets/samples/'
);
$this->load->library('upload',$config);
//echo 'about to upload';
if ($this->upload->do_upload('trackfile')) {
$file_data = $this->upload->data();
//echo 'uploaded: <pre>'; print_r($file_data); echo '</pre>'; die();
$track_data['trackfile'] = $file_data['file_name'];
$this->db->where('id', $insert_id);
return $this->db->update('table_name',$track_data);
} else {
echo 'Failed: ';
echo $this->upload->display_errors();
echo 'FILE DATA: <pre>'; print_r($_FILES['trackfile']); echo '</pre>';
}
}
My problem is that this produces the error "The filetype you are attempting to upload is not allowed." I've checked the mp3 type, it's audio/mpeg, which is in the mimes.php file.
This only happens when I'm also uploading an image. If I leave the image field blank, the mp3 uploads fine. Any help much appreciated.
EDIT
According to the CI docs, the allowed_types portion of the config is a pipe delimited list of mime types, not file extensions. For example, mp3 have the mime type 'audio/mpeg'. So your allowed_types config should look like this:
$config = array(
'allowed_types' => 'audo/mpeg|audio/x-wav|audio/x-aiff|application/ogg',
'upload_path' => './assets/samples/'
);
If that doesn't work try to initialize the library as mentioned here.

Multi-dimensional array parsed from .csv ->commas causing mysql database insert issues

I am using Codeigniter to parse an uploaded csv file (which is a multi-dimensional array) into a database. I have tried everything to parse the comma values correctly, but the "id" column in mysql comes up short, as it reads "text", and not "text,text,text". Help!?
*For reference:*
print_r($data['csvData']);
Array ( [0] => Array ( [category,id] => text1,"text,text,text" )
[1] => Array ( [category,id] => text2,"text,text,text" )
)
foreach($data['csvData'] as $row) {
foreach ($row as $item) {
$item=explode(",", $item);
$results_array = array(
'category' => $item[0],
'id' => $item[1]
);
$this->db->set($results_array);
$this->db->insert('table', $results_array);
}
}
My uneducated guess:
$item=explode(",", $item); is exploding $item which is text1,"text,text,text", right? So it sees 4 commas, and explodes them. Therefore $item[0] will be "text1, $item[1] will be "text" $item[2] will be "text" and $item[3] will be "text".
You can try to set your delimiter in the csv as something other than a comma, and explode that.
Or you can concatenate the other items before inserting them into the db:
$item = explode(",", $item);
$id_insert = $item[1].$item[2].$item[3];
//if you need to retain the commas in the id:
//$id_insert = $item[1].','.$item[2].','.$item[3];
$results_array = array(
'category' => $item[0],
'id' => $id_insert,
);
$this->db->set($results_array);
$this->db->insert('table', $results_array);

Resources