From 41909ff8e0852fca8d0e2889fde1aace679a5d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Tue, 14 Sep 2021 10:58:00 +0200 Subject: [PATCH] Question export --- app/Http/Controllers/QuestionController.php | 86 +++++++++++++++++++ app/Http/Requests/QuestionExport.php | 30 +++++++ .../views/layouts/backend/sidenav.blade.php | 7 +- resources/views/question/export.blade.php | 53 ++++++++++++ resources/views/question/index.blade.php | 1 - routes/web.php | 5 +- 6 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 app/Http/Requests/QuestionExport.php create mode 100644 resources/views/question/export.blade.php diff --git a/app/Http/Controllers/QuestionController.php b/app/Http/Controllers/QuestionController.php index 2fab894..2d0284c 100644 --- a/app/Http/Controllers/QuestionController.php +++ b/app/Http/Controllers/QuestionController.php @@ -3,10 +3,17 @@ namespace App\Http\Controllers; use App\Http\Controllers\Controller; +use App\Http\Requests\QuestionExport; +use App\Models\Brand; use App\Models\Question; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Str; use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest; use Kwaadpepper\CrudPolicies\Traits\CrudController; +use League\Csv\Writer; +use Symfony\Component\HttpFoundation\StreamedResponse; class QuestionController extends Controller { @@ -36,4 +43,83 @@ class QuestionController extends Controller } return $query; } + + public function export() + { + $brands = Brand::all(); + return view('question.export', compact('brands')); + } + + public function exportSubmit(QuestionExport $request) + { + $results = []; + $brand = Brand::findOrFail($request->brand); + $questions = $brand->questions->load('answers'); + + foreach ($questions as $question) { + $answersCounts = DB::query() + ->selectRaw('count(*) as total, answer_id') + ->from('customer_answer') + ->whereIn('answer_id', $question->answers->pluck('id')) + ->groupBy('answer_id') + ->get()->keyBy('answer_id'); + + $results[$question->id] = [ + 'question' => $question->question, + 'answers' => [] + ]; + foreach ($question->answers as $answer) { + $results[$question->id]['answers'][] = + [ + "$answer->answer ", + $answersCounts[$answer->id]->total ?? 0 + ]; + } + } + + $pagination = 2000; + + $w = Writer::createFromString(''); + $w->setDelimiter(';'); + $w->setEnclosure('"'); + $w->setOutputBOM(Writer::BOM_UTF8); + + //We send the CSV using Symfony StreamedResponse + $response = new StreamedResponse(); + $response->headers->set('Content-Encoding', 'none'); + $response->headers->set('Content-Type', 'text/csv; charset=UTF-8'); + $response->headers->set('Description', 'File Transfer'); + $response->headers->set( + 'Content-Disposition', + sprintf( + 'attachment; filename="Export pour newsletter %s %s.csv"', + Carbon::now()->format('d-m-Y_H-i'), + Str::slug($brand->name) + ) + ); + + foreach ($results as $result) { + $w->insertOne([ + 'question' => $result['question'], + ]); + foreach ($result['answers'] as $answer) { + $w->insertOne($answer); + } + $w->insertOne([]); + } + + //we create a callable to output the CSV in chunk + //with Symfony StreamResponse you can flush the body content if necessary + //see Symfony documentation for more information + $flush_threshold = 1000; //the flush value should depend on your CSV size. + $response->setCallback(function () use ($w, $flush_threshold) { + foreach ($w->chunk(1024) as $offset => $chunk) { + echo $chunk; + if ($offset % $flush_threshold === 0) { + flush(); + } + } + }); + return $response; + } } diff --git a/app/Http/Requests/QuestionExport.php b/app/Http/Requests/QuestionExport.php new file mode 100644 index 0000000..8ef5ca7 --- /dev/null +++ b/app/Http/Requests/QuestionExport.php @@ -0,0 +1,30 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'brand' => 'required|numeric|exists:brands,id' + ]; + } +} diff --git a/resources/views/layouts/backend/sidenav.blade.php b/resources/views/layouts/backend/sidenav.blade.php index 306b120..dd36dca 100644 --- a/resources/views/layouts/backend/sidenav.blade.php +++ b/resources/views/layouts/backend/sidenav.blade.php @@ -42,7 +42,12 @@ @endcan @endforeach + +