authorizeResource(Question::class); } /** * Display a listing of the resource. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Contracts\View\View */ public function index(Request $request): \Illuminate\Contracts\View\View { /** @var \Illuminate\Database\Eloquent\Builder $query */ $query = Question::query()->when( $request->filled('brand'), fn($q) => $q->whereHas('brand', fn($q) => $q->where('id', $request->brand)) ); if ($request->search) { $this->searchQuery( $query, $request->search, null, 'question', ); } $this->sortQuery($query); $searchFields = trans('Question'); $query->with(['brand', 'answers']); /** @var \Illuminate\Pagination\AbstractPaginator */ $questionModels = $query->paginate($this->getPagination()); return view('bo.pages.questions.index', compact('questionModels', 'searchFields')); } /** * Show the form for creating a new resource. * * @param \App\Models\Question $question * @return \Illuminate\Contracts\View\View */ public function create(Question $question): \Illuminate\Contracts\View\View { $brandModels = Brand::query()->orderBy('name', 'ASC')->paginate($this->jsonItemPerPagination); return view('bo.pages.questions.create', [ 'questionModel' => $question, 'brandModels' => $brandModels ]); } /** * Store a newly created resource in storage. * * @param \App\Http\Requests\Questions\StoreQuestionRequest $request * @return \Illuminate\Http\RedirectResponse */ public function store(StoreQuestionRequest $request): \Illuminate\Http\RedirectResponse { return DB::transaction(function () use ($request) { $question = new Question(); $question->fill($request->validated()); if ($question->saveOrFail()) { return redirect() ->route('bo.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\Contracts\View\View */ public function edit(Question $question): \Illuminate\Contracts\View\View { $brandModels = Brand::query()->orderBy('name', 'ASC')->paginate($this->jsonItemPerPagination); $question->load('brand'); return view('bo.pages.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\RedirectResponse */ public function update(UpdateQuestionRequest $request, Question $question): \Illuminate\Http\RedirectResponse { return DB::transaction(function () use ($request, $question) { $question->fill($request->validated()); if ($question->saveOrFail()) { return redirect() ->route('bo.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\Contracts\View\View */ public function show(Question $question): \Illuminate\Contracts\View\View { return view('bo.pages.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('bo.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\Contracts\View\View */ public function export(): \Illuminate\Contracts\View\View { $this->authorize('export', Question::class); $brands = Brand::all(); return view('bo.pages.questions.export', compact('brands')); } /** * Exports questions as csv the requested export type * * @param \App\Http\Requests\QuestionExport $request * @return \Symfony\Component\HttpFoundation\StreamedResponse */ public function exportSubmit(QuestionExport $request): \Symfony\Component\HttpFoundation\StreamedResponse { $results = []; /** @var \App\Models\Brand $brand */ $brand = Brand::query()->where('id', $request->brand)->firstOrFail(); $questions = $brand->questions->load('answers'); foreach ($questions as $question) { $answersCounts = DB::query() ->selectRaw('count(*) as total, answer_id') ->from('model_answer') ->where('model_type', '=', Customer::class) ->whereIn('answer_id', $question->answers->modelKeys()) ->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 ]; } } //end foreach $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()->isoFormat('DD-MM-YYYY_HH-mm'), Str::slug($brand->name) ) ); foreach ($results as $result) { $w->insertOne([ 'question' => $result['question'], ]); foreach ($result['answers'] as $answer) { $w->insertOne($answer); } $w->insertOne([]); } // * Push empty line if nothing to export if (empty($results)) { $w->insertOne([ 'Aucune question pour cette marque' ]); } /* 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; } }