Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
QuestionController
n/a
0 / 0
n/a
0 / 0
12
n/a
0 / 0
 indexQuery
n/a
0 / 0
2
n/a
0 / 0
 index
n/a
0 / 0
2
n/a
0 / 0
 export
n/a
0 / 0
1
n/a
0 / 0
 exportSubmit
n/a
0 / 0
7
n/a
0 / 0
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Http\Controllers\Controller;
6use App\Http\Requests\QuestionExport;
7use App\Models\Brand;
8use App\Models\Question;
9use Carbon\Carbon;
10use Illuminate\Database\Eloquent\Builder;
11use Illuminate\Support\Facades\DB;
12use Illuminate\Support\Str;
13use Kwaadpepper\CrudPolicies\Http\Requests\CrudIndexRequest;
14use Kwaadpepper\CrudPolicies\Traits\CrudController;
15use League\Csv\Writer;
16use Symfony\Component\HttpFoundation\StreamedResponse;
17
18/**
19 * @codeCoverageIgnore
20 */
21class QuestionController extends Controller
22{
23    use CrudController {
24        index as crudIndex;
25    }
26
27    /** @var Question */
28    public static $modelClass = Question::class;
29
30    /**
31     * The Bo app layout
32     *
33     * @var string
34     */
35    public static $layout = 'layouts.app';
36
37    /**
38     * Event index crud-policies
39     *
40     * @param Builder $query
41     * @return Builder
42     */
43    public function indexQuery(Builder $query): Builder
44    {
45        if (request()->brand) {
46            $query = $query->where('brand_id', '=', request()->brand);
47        }
48        return $query;
49    }
50
51    /**
52     * Overload crud-policies index
53     *
54     * @param CrudIndexRequest $request
55     * @return \Illuminate\Http\Response
56     */
57    public function index(CrudIndexRequest $request)
58    {
59        /** @var \Illuminate\View\View */
60        $view = $this->crudIndex($request);
61        if ($request->ajax()) {
62            return $view;
63        }
64        return view('question.index', $view->getData());
65    }
66
67    /**
68     * Shows the question export form
69     *
70     * @return \Illuminate\Http\Response
71     */
72    public function export()
73    {
74        $brands = Brand::all();
75        return view('question.export', compact('brands'));
76    }
77
78    /**
79     * Exports questions as csv the requested export type
80     *
81     * @param QuestionExport $request
82     * @return \Symfony\Component\HttpFoundation\StreamedResponse
83     */
84    public function exportSubmit(QuestionExport $request)
85    {
86        $results   = [];
87        $brand     = Brand::findOrFail($request->brand);
88        $questions = $brand->questions->load('answers');
89
90        foreach ($questions as $question) {
91            $answersCounts = DB::query()
92                ->selectRaw('count(*) as total, answer_id')
93                ->from('customer_answer')
94                ->whereIn('answer_id', $question->answers->pluck('id'))
95                ->groupBy('answer_id')
96                ->get()->keyBy('answer_id');
97
98            $results[$question->id] = [
99                'question' => $question->question,
100                'answers' => []
101            ];
102            foreach ($question->answers as $answer) {
103                $results[$question->id]['answers'][] =
104                    [
105                        "$answer->answer ",
106                        $answersCounts[$answer->id]->total ?? 0
107                    ];
108            }
109        }
110
111        $w = Writer::createFromString('');
112        $w->setDelimiter(';');
113        $w->setEnclosure('"');
114        $w->setOutputBOM(Writer::BOM_UTF8);
115
116        // * We send the CSV using Symfony StreamedResponse.
117        $response = new StreamedResponse();
118        $response->headers->set('Content-Encoding', 'none');
119        $response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
120        $response->headers->set('Description', 'File Transfer');
121        $response->headers->set(
122            'Content-Disposition',
123            sprintf(
124                'attachment; filename="Export pour newsletter %s %s.csv"',
125                Carbon::now()->format('d-m-Y_H-i'),
126                Str::slug($brand->name)
127            )
128        );
129
130        foreach ($results as $result) {
131            $w->insertOne([
132                'question' => $result['question'],
133            ]);
134            foreach ($result['answers'] as $answer) {
135                $w->insertOne($answer);
136            }
137            $w->insertOne([]);
138        }
139
140        /*
141            We create a callable to output the CSV in chunk
142            with Symfony StreamResponse you can flush the body content if necessary
143            see Symfony documentation for more information
144        */
145
146        // * The flush value should depend on your CSV size.
147        $flush_threshold = 1000;
148
149        $response->setCallback(function () use ($w, $flush_threshold) {
150            foreach ($w->chunk(1024) as $offset => $chunk) {
151                echo $chunk;
152                if ($offset % $flush_threshold === 0) {
153                    flush();
154                }
155            }
156        });
157        return $response;
158    }
159}