125 lines
3.9 KiB
PHP
125 lines
3.9 KiB
PHP
<?php
|
|
|
|
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
|
|
{
|
|
use CrudController {
|
|
index as crudIndex;
|
|
}
|
|
|
|
/** @var Question */
|
|
public static $modelClass = Question::class;
|
|
|
|
public static $layout = 'layouts.app';
|
|
|
|
public function index(CrudIndexRequest $request)
|
|
{
|
|
/** @var \Illuminate\View\View */
|
|
$view = $this->crudIndex($request);
|
|
if ($request->ajax()) {
|
|
return $view;
|
|
}
|
|
return view('question.index', $view->getData());
|
|
}
|
|
|
|
public function indexQuery(Builder $query): Builder
|
|
{
|
|
if (request()->brand) {
|
|
$query = $query->where('brand_id', '=', request()->brand);
|
|
}
|
|
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;
|
|
}
|
|
}
|