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
21
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
 jsonPaginate
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 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     * Store a newly created resource in storage.
191     *
192     * @return \Illuminate\Http\Response
193     */
194    public function jsonPaginate()
195    {
196        return DB::transaction(function () {
197            /** @var \App\Models\Tag */
198            $brandModels = Brand::paginate(12);
199            return \response()->json($brandModels ?? 500);
200        });
201    }
202
203    /**
204     * Exports questions as csv the requested export type
205     *
206     * @param QuestionExport $request
207     * @return \Symfony\Component\HttpFoundation\StreamedResponse
208     */
209    public function exportSubmit(QuestionExport $request)
210    {
211        $results   = [];
212        $brand     = Brand::findOrFail($request->brand);
213        $questions = $brand->questions->load('answers');
214
215        foreach ($questions as $question) {
216            $answersCounts = DB::query()
217                ->selectRaw('count(*) as total, answer_id')
218                ->from('customer_answer')
219                ->whereIn('answer_id', $question->answers->pluck('id'))
220                ->groupBy('answer_id')
221                ->get()->keyBy('answer_id');
222
223            $results[$question->id] = [
224                'question' => $question->question,
225                'answers' => []
226            ];
227            foreach ($question->answers as $answer) {
228                $results[$question->id]['answers'][] =
229                    [
230                        "$answer->answer ",
231                        $answersCounts[$answer->id]->total ?? 0
232                    ];
233            }
234        }
235
236        $w = Writer::createFromString('');
237        $w->setDelimiter(';');
238        $w->setEnclosure('"');
239        $w->setOutputBOM(Writer::BOM_UTF8);
240
241        // * We send the CSV using Symfony StreamedResponse.
242        $response = new StreamedResponse();
243        $response->headers->set('Content-Encoding', 'none');
244        $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
245        $response->headers->set('Description', 'File Transfer');
246        $response->headers->set(
247            'Content-Disposition',
248            sprintf(
249                'attachment; filename="Export pour newsletter %s %s.csv"',
250                Carbon::now()->format('d-m-Y_H-i'),
251                Str::slug($brand->name)
252            )
253        );
254
255        foreach ($results as $result) {
256            $w->insertOne([
257                'question' => $result['question'],
258            ]);
259            foreach ($result['answers'] as $answer) {
260                $w->insertOne($answer);
261            }
262            $w->insertOne([]);
263        }
264
265        /*
266            We create a callable to output the CSV in chunk
267            with Symfony StreamResponse you can flush the body content if necessary
268            see Symfony documentation for more information
269        */
270
271        // * The flush value should depend on your CSV size.
272        $flush_threshold = 1000;
273
274        $response->setCallback(function () use ($w, $flush_threshold) {
275            foreach ($w->chunk(1024) as $offset => $chunk) {
276                echo $chunk;
277                if ($offset % $flush_threshold === 0) {
278                    flush();
279                }
280            }
281        });
282        return $response;
283    }
284}