Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
QuestionController
n/a
0 / 0
n/a
0 / 0
20
n/a
0 / 0
 index
n/a
0 / 0
n/a
0 / 0
3
 create
n/a
0 / 0
n/a
0 / 0
1
 store
n/a
0 / 0
n/a
0 / 0
2
 edit
n/a
0 / 0
n/a
0 / 0
1
 update
n/a
0 / 0
n/a
0 / 0
2
 show
n/a
0 / 0
n/a
0 / 0
1
 destroy
n/a
0 / 0
n/a
0 / 0
2
 export
n/a
0 / 0
n/a
0 / 0
1
 exportSubmit
n/a
0 / 0
n/a
0 / 0
7
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Http\Controllers\Controller;
6use App\Http\Requests\QuestionExport;
7use App\Http\Requests\Questions\StoreQuestionRequest;
8use App\Http\Requests\Questions\UpdateQuestionRequest;
9use App\Models\Brand;
10use App\Models\Question;
11use Carbon\Carbon;
12use Illuminate\Http\Request;
13use Illuminate\Support\Facades\DB;
14use Illuminate\Support\Str;
15use League\Csv\Writer;
16use Symfony\Component\HttpFoundation\StreamedResponse;
17
18/**
19 * @codeCoverageIgnore
20 */
21class QuestionController extends Controller
22{
23    /**
24     * Display a listing of the resource.
25     *
26     * @param \Illuminate\Http\Request $request
27     * @return \Illuminate\Http\Response
28     */
29    public function index(Request $request)
30    {
31        /** @var \Illuminate\Database\Eloquent\Builder $query */
32        $query = Question::query();
33
34        if ($request->brand) {
35            $query = $query->where('brand_id', '=', request()->brand);
36        }
37        if ($request->search) {
38            $this->searchQuery(
39                $query,
40                $request->search,
41                null,
42                'question',
43            );
44        }
45
46        $this->sortQuery($query);
47        $searchFields = trans('Question');
48
49        /** @var \Illuminate\Pagination\AbstractPaginator */
50        $questionModels = $query->paginate(12);
51
52        return view('questions.index', compact('questionModels', 'searchFields'));
53    }
54
55    /**
56     * Show the form for creating a new resource.
57     *
58     * @param \App\Models\Question $question
59     * @return \Illuminate\Http\Response
60     */
61    public function create(Question $question)
62    {
63        $brandModels = Brand::get();
64
65        return view('questions.create', [
66            'questionModel' => $question,
67            'brandModels' => $brandModels
68        ]);
69    }
70
71    /**
72     * Store a newly created resource in storage.
73     *
74     * @param \App\Http\Requests\Questions\StoreQuestionRequest $request
75     * @return \Illuminate\Http\Response
76     */
77    public function store(StoreQuestionRequest $request)
78    {
79        return DB::transaction(function () use ($request) {
80            $question = new Question();
81            $question->fill($request->validated());
82            if ($question->saveOrFail()) {
83                return redirect()
84                    ->route('questions.edit', $question)
85                    ->with('success', trans(
86                        ':model a été créé.',
87                        ['model' => Str::singular(trans('models.classes.questions'))]
88                    ));
89            }
90            return redirect()
91                ->back()
92                ->with('error', trans(
93                    ':model n\'a pas été créé.',
94                    ['model' => Str::singular(trans('models.classes.questions'))]
95                ));
96        });
97    }
98
99    /**
100     * Show the form for editing the specified resource.
101     *
102     * @param \App\Models\Question $question
103     * @return \Illuminate\Http\Response
104     */
105    public function edit(Question $question)
106    {
107        $brandModels = Brand::get();
108
109        return view('questions.edit', [
110            'questionModel' => $question,
111            'brandModels' => $brandModels
112        ]);
113    }
114
115    /**
116     * Update a spacific resource in storage.
117     *
118     * @param \App\Http\Requests\Questions\UpdateQuestionRequest $request
119     * @param \App\Models\Question                               $question
120     * @return \Illuminate\Http\Response
121     */
122    public function update(UpdateQuestionRequest $request, Question $question)
123    {
124        return DB::transaction(function () use ($request, $question) {
125            $question->fill($request->validated());
126            if ($question->saveOrFail()) {
127                return redirect()
128                    ->route('questions.edit', $question)
129                    ->with('success', trans(
130                        ':model a été mis à jour.',
131                        ['model' => Str::singular(trans('models.classes.questions'))]
132                    ));
133            }
134            return redirect()
135                ->back()
136                ->with('error', trans(
137                    ':model n\'a pas été mis à jour.',
138                    ['model' => Str::singular(trans('models.classes.questions'))]
139                ));
140        });
141    }
142
143    /**
144     * Show the specified resource.
145     *
146     * @param \App\Models\Question $question
147     * @return \Illuminate\Http\Response
148     */
149    public function show(Question $question)
150    {
151        return view('questions.show', [
152            'questionModel' => $question
153        ]);
154    }
155
156    /**
157     * Remove the specified resource from storage.
158     *
159     * @param \App\Models\Question $question
160     * @return \Illuminate\Http\RedirectResponse
161     */
162    public function destroy(Question $question): \Illuminate\Http\RedirectResponse
163    {
164        if ($question->deleteOrFail()) {
165            return redirect()->route('questions.index')
166                ->with('success', trans(
167                    ':model a été supprimé.',
168                    ['model' => Str::singular(trans('models.classes.questions'))]
169                ));
170        }
171        return redirect()->back()
172            ->with('error', trans(
173                ':model n\'a pas pu être supprimé.',
174                ['model' => Str::singular(trans('models.classes.questions'))]
175            ));
176    }
177
178    /**
179     * Shows the question export form
180     *
181     * @return \Illuminate\Http\Response
182     */
183    public function export()
184    {
185        $brands = Brand::all();
186        return view('questions.export', compact('brands'));
187    }
188
189    /**
190     * Exports questions as csv the requested export type
191     *
192     * @param \App\Http\Requests\QuestionExport $request
193     * @return \Symfony\Component\HttpFoundation\StreamedResponse
194     */
195    public function exportSubmit(QuestionExport $request)
196    {
197        $results   = [];
198        $brand     = Brand::findOrFail($request->brand);
199        $questions = $brand->questions->load('answers');
200
201        foreach ($questions as $question) {
202            $answersCounts = DB::query()
203                ->selectRaw('count(*) as total, answer_id')
204                ->from('customer_answer')
205                ->whereIn('answer_id', $question->answers->pluck('id'))
206                ->groupBy('answer_id')
207                ->get()->keyBy('answer_id');
208
209            $results[$question->id] = [
210                'question' => $question->question,
211                'answers' => []
212            ];
213            foreach ($question->answers as $answer) {
214                $results[$question->id]['answers'][] =
215                    [
216                        "$answer->answer ",
217                        $answersCounts[$answer->id]->total ?? 0
218                    ];
219            }
220        }
221
222        $w = Writer::createFromString('');
223        $w->setDelimiter(';');
224        $w->setEnclosure('"');
225        $w->setOutputBOM(Writer::BOM_UTF8);
226
227        // * We send the CSV using Symfony StreamedResponse.
228        $response = new StreamedResponse();
229        $response->headers->set('Content-Encoding', 'none');
230        $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
231        $response->headers->set('Description', 'File Transfer');
232        $response->headers->set(
233            'Content-Disposition',
234            sprintf(
235                'attachment; filename="Export pour newsletter %s %s.csv"',
236                Carbon::now()->format('d-m-Y_H-i'),
237                Str::slug($brand->name)
238            )
239        );
240
241        foreach ($results as $result) {
242            $w->insertOne([
243                'question' => $result['question'],
244            ]);
245            foreach ($result['answers'] as $answer) {
246                $w->insertOne($answer);
247            }
248            $w->insertOne([]);
249        }
250
251        /*
252            We create a callable to output the CSV in chunk
253            with Symfony StreamResponse you can flush the body content if necessary
254            see Symfony documentation for more information
255        */
256
257        // * The flush value should depend on your CSV size.
258        $flush_threshold = 1000;
259
260        $response->setCallback(function () use ($w, $flush_threshold) {
261            foreach ($w->chunk(1024) as $offset => $chunk) {
262                echo $chunk;
263                if ($offset % $flush_threshold === 0) {
264                    flush();
265                }
266            }
267        });
268        return $response;
269    }
270}