284 lines
8.6 KiB
PHP
284 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Requests\QuestionExport;
|
|
use App\Http\Requests\Questions\StoreQuestionRequest;
|
|
use App\Http\Requests\Questions\UpdateQuestionRequest;
|
|
use App\Models\Brand;
|
|
use App\Models\Question;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use League\Csv\Writer;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
/**
|
|
* @codeCoverageIgnore
|
|
*/
|
|
class QuestionController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of the resource.
|
|
*
|
|
* @param Request $request
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
|
$query = Question::query();
|
|
|
|
if ($request->brand) {
|
|
$query = $query->where('brand_id', '=', request()->brand);
|
|
}
|
|
if ($request->search) {
|
|
$this->searchQuery(
|
|
$query,
|
|
$request->search,
|
|
null,
|
|
'question',
|
|
);
|
|
}
|
|
|
|
$this->sortQuery($query);
|
|
$searchFields = trans('Question');
|
|
|
|
/** @var \Illuminate\Pagination\AbstractPaginator */
|
|
$questionModels = $query->paginate(12);
|
|
|
|
return view('questions.index', compact('questionModels', 'searchFields'));
|
|
}
|
|
|
|
/**
|
|
* Show the form for creating a new resource.
|
|
*
|
|
* @param \App\Models\Question $question
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function create(Question $question)
|
|
{
|
|
$brandModels = Brand::get();
|
|
|
|
return view('questions.create', [
|
|
'questionModel' => $question,
|
|
'brandModels' => $brandModels
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Store a newly created resource in storage.
|
|
*
|
|
* @param \App\Http\Requests\Questions\StoreQuestionRequest $request
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function store(StoreQuestionRequest $request)
|
|
{
|
|
return DB::transaction(function () use ($request) {
|
|
$question = new Question();
|
|
$question->fill($request->validated());
|
|
if ($question->saveOrFail()) {
|
|
return redirect()
|
|
->route('questions.edit', $question)
|
|
->with('success', trans(
|
|
':model a été créé.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
}
|
|
return redirect()
|
|
->back()
|
|
->with('error', trans(
|
|
':model n\'a pas été créé.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified resource.
|
|
*
|
|
* @param \App\Models\Question $question
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function edit(Question $question)
|
|
{
|
|
$brandModels = Brand::get();
|
|
|
|
return view('questions.edit', [
|
|
'questionModel' => $question,
|
|
'brandModels' => $brandModels
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Update a spacific resource in storage.
|
|
*
|
|
* @param \App\Http\Requests\Questions\UpdateQuestionRequest $request
|
|
* @param \App\Models\Question $question
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function update(UpdateQuestionRequest $request, Question $question)
|
|
{
|
|
return DB::transaction(function () use ($request, $question) {
|
|
$question->fill($request->validated());
|
|
if ($question->saveOrFail()) {
|
|
return redirect()
|
|
->route('questions.edit', $question)
|
|
->with('success', trans(
|
|
':model a été mis à jour.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
}
|
|
return redirect()
|
|
->back()
|
|
->with('error', trans(
|
|
':model n\'a pas été mis à jour.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show the specified resource.
|
|
*
|
|
* @param \App\Models\Question $question
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function show(Question $question)
|
|
{
|
|
return view('questions.show', [
|
|
'questionModel' => $question
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Remove the specified resource from storage.
|
|
*
|
|
* @param \App\Models\Question $question
|
|
* @return \Illuminate\Http\RedirectResponse
|
|
*/
|
|
public function destroy(Question $question): \Illuminate\Http\RedirectResponse
|
|
{
|
|
if ($question->deleteOrFail()) {
|
|
return redirect()->route('questions.index')
|
|
->with('success', trans(
|
|
':model a été supprimé.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
}
|
|
return redirect()->back()
|
|
->with('error', trans(
|
|
':model n\'a pas pu être supprimé.',
|
|
['model' => Str::singular(trans('models.classes.questions'))]
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Shows the question export form
|
|
*
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function export()
|
|
{
|
|
$brands = Brand::all();
|
|
return view('questions.export', compact('brands'));
|
|
}
|
|
|
|
/**
|
|
* Store a newly created resource in storage.
|
|
*
|
|
* @return \Illuminate\Http\Response
|
|
*/
|
|
public function jsonPaginate()
|
|
{
|
|
return DB::transaction(function () {
|
|
/** @var \App\Models\Tag */
|
|
$brandModels = Brand::paginate(12);
|
|
return \response()->json($brandModels ?? 500);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Exports questions as csv the requested export type
|
|
*
|
|
* @param QuestionExport $request
|
|
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
|
*/
|
|
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
|
|
];
|
|
}
|
|
}
|
|
|
|
$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
|
|
*/
|
|
|
|
// * The flush value should depend on your CSV size.
|
|
$flush_threshold = 1000;
|
|
|
|
$response->setCallback(function () use ($w, $flush_threshold) {
|
|
foreach ($w->chunk(1024) as $offset => $chunk) {
|
|
echo $chunk;
|
|
if ($offset % $flush_threshold === 0) {
|
|
flush();
|
|
}
|
|
}
|
|
});
|
|
return $response;
|
|
}
|
|
}
|