InterviewController.php 7.66 KB
Newer Older
ZeMKI's avatar
ZeMKI committed
1
2
3
4
<?php

namespace App\Http\Controllers;

Alessandro Belli's avatar
Alessandro Belli committed
5
use App\Answer;
Alessandro Belli's avatar
Alessandro Belli committed
6
use App\Exports\InterviewTokenExport;
Alessandro Belli's avatar
Alessandro Belli committed
7
8
use App\Files;
use App\Interview;
ZeMKI's avatar
ZeMKI committed
9
use App\Sorting;
Alessandro Belli's avatar
Alessandro Belli committed
10
use App\Study;
11
use App\Token;
Alessandro Belli's avatar
Alessandro Belli committed
12
use App\User;
13
use Auth;
Alessandro Belli's avatar
Alessandro Belli committed
14
use DB;
Alessandro Belli's avatar
Alessandro Belli committed
15
use Exception;
16
17
use File;
use Helper;
Alessandro Belli's avatar
Alessandro Belli committed
18
19
20
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\View\Factory;
21
use Illuminate\Http\Request;
Alessandro Belli's avatar
Alessandro Belli committed
22
use Illuminate\Http\Response;
Alessandro Belli's avatar
Alessandro Belli committed
23
24
use Illuminate\View\View;
use Storage;
ZeMKI's avatar
ZeMKI committed
25
use Symfony\Component\HttpFoundation\BinaryFileResponse;
ZeMKI's avatar
ZeMKI committed
26
27
28

class InterviewController extends Controller
{
Laravel Shift's avatar
Laravel Shift committed
29
30
    public function show(Interview $interview)
    {
ZeMKI's avatar
ZeMKI committed
31
        $this->authorize($interview);
32
        $data['interview'] = $interview;
Alessandro Belli's avatar
Alessandro Belli committed
33
        $data['screenshots'] = [];
Laravel Shift's avatar
Laravel Shift committed
34
        $data['sortingtoken'] = $interview->tokens;
ZeMKI's avatar
ZeMKI committed
35
        $data['tokens'] = $interview->study->available_tokens;
Alessandro Belli's avatar
Alessandro Belli committed
36
        $data['createdtokens'] = Token::formatForEdit($interview->tokens()->where('tokens.author', '=', 0)->get());
ZeMKI's avatar
ZeMKI committed
37
38
39
        $data['study'] = $interview->study;
        $data['questions'] = $interview->study->questions;
        $data['sorting'] = $interview->study->sortings[0];
ZeMKI's avatar
ZeMKI committed
40
        $data['author'] = User::where('id', $interview->author)->first()->email ?? $interview->author;
Alessandro Belli's avatar
Alessandro Belli committed
41
        Answer::assignAnswersToQuestion($interview, $data);
ZeMKI's avatar
ZeMKI committed
42
        Sorting::getSortingInfo($interview->study, $data);
Alessandro Belli's avatar
Alessandro Belli committed
43
        Interview::getSortingImages($interview, $data);
Laravel Shift's avatar
Laravel Shift committed
44
45
46
        return view('interview.view', $data);
    }

47
48
    /**
     * SHOW THE CREATE INTERVIEW PAGE
49
     * gather the data and format them in a correct way for the frontend.
50
51
52
     * @param Request $request
     * @return Factory|View
     * @throws AuthorizationException
53
     */
Laravel Shift's avatar
Laravel Shift committed
54
55
    public function create(Request $request)
    {
ZeMKI's avatar
ZeMKI committed
56
57
        if(auth()->check()) $this->authorize([Interview::class, $request->input('study')]);

58
        /** Extract method FORMATQUESTIONSANSWERS */
ZeMKI's avatar
ZeMKI committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
        $this->FormatQuestionsAndAnswers($request, $returnQuestions);
        $data['questions'] = $returnQuestions;
        $data['study'] = Study::where('id', '=', $request->input('study'))->with('sortings')->first();
        $data['interviewed'] = htmlspecialchars($request->has('interviewed') && ltrim($request->input('interviewed')) !== '' ? $request->input('interviewed') : 'Name not provided');
        $data['sorting'] = $data['study']->sortings[0];
        $data['tokens'] = $data['study']->available_tokens;
        $data['presetimages'] = Helper::getPresetImages();
        $data['classifiers'] = Helper::getClassifiers();
        /** extract method GETTOKENS */
        $this->GetTokensForInterview($data);
        // FLAG FOR DEBUG - GO DIRECTLY INTO SORTING PAGE
        $data['gotos'] = $request->input('gotos') ? 'true' : 'false';
        return view('interview.create', $data);
    }

    /**
     * @param Request $request
     * @param         $returnQuestions
     */
    private function FormatQuestionsAndAnswers(Request $request, &$returnQuestions): void
    {
80
81
        $query = '
        select distinct qid, q, type,
ZeMKI's avatar
ZeMKI committed
82
83
84
        GROUP_CONCAT(answer SEPARATOR ",") as answer,
        GROUP_CONCAT(answers.id SEPARATOR ",") as answerids
        from (
85
        Select distinct questions.id as qid, questions.question as q, questions.detail as type
ZeMKI's avatar
ZeMKI committed
86
        from questions
Alessandro Belli's avatar
Alessandro Belli committed
87
        where `study_id` = ' . $request->input('study') . '
ZeMKI's avatar
ZeMKI committed
88
89
        ) as qtable
        left join `answers` on qid = `answers`.`question_id`
90
        group by qid,q,type';
Laravel Shift's avatar
Laravel Shift committed
91
        $questions = DB::select(DB::raw($query));
ZeMKI's avatar
ZeMKI committed
92
        $returnQuestions['presort'] = $returnQuestions['postsort'] = [];
93
        foreach ($questions as $question) {
Alessandro Belli's avatar
Alessandro Belli committed
94
            $question->answer = json_decode('[' . $question->answer . ']');
95
96
97
            $question->answer['ids'] = explode(',', $question->answerids);
            if ($question->type === 'presort') {
                array_push($returnQuestions['presort'], $question);
Laravel Shift's avatar
Laravel Shift committed
98
            }
99
100
            if ($question->type === 'postsort') {
                array_push($returnQuestions['postsort'], $question);
Laravel Shift's avatar
Laravel Shift committed
101
102
            }
        }
ZeMKI's avatar
ZeMKI committed
103
    }
Alessandro Belli's avatar
Alessandro Belli committed
104

ZeMKI's avatar
ZeMKI committed
105
106
107
108
109
    /**
     * @param $data
     */
    private function GetTokensForInterview(&$data): void
    {
110
111
        $TokensCount = count($data['tokens']);
        for ($i = 0; $i < $TokensCount; $i++) {
ZeMKI's avatar
ZeMKI committed
112
113
            if (strpos($data['tokens'][$i]['image_path'], 'presets') !== false) {
                $path = $data['tokens'][$i]['image_path'];
114
                $data['tokens'][$i]['image_path'] = mb_convert_encoding($path, 'HTML-ENTITIES', 'UTF-8');
115
            } else {
Alessandro Belli's avatar
Alessandro Belli committed
116
                $path = storage_path('app/' . $data['tokens'][$i]['image_path']);
117
                $data['tokens'][$i]['image_path'] = decrypt(file_get_contents($path));
ZeMKI's avatar
ZeMKI committed
118
            }
Laravel Shift's avatar
Laravel Shift committed
119
120
        }
    }
ZeMKI's avatar
ZeMKI committed
121

Laravel Shift's avatar
Laravel Shift committed
122
123
124
    public function store(Request $request)
    {
        $study = Study::where('id', '=', $request->input('study'))->first();
ZeMKI's avatar
ZeMKI committed
125
126
127

        $author = auth()->check() ? Auth::user()->id : 'From public url.';

Alessandro Belli's avatar
Alessandro Belli committed
128
        $interview = new Interview();
Laravel Shift's avatar
Laravel Shift committed
129
        $interview->study_id = $study->id;
ZeMKI's avatar
ZeMKI committed
130
        $interview->author = $author;
Laravel Shift's avatar
Laravel Shift committed
131
132
133
134
        $interview->interviewed = $request->input('interviewed');
        $interview->start = $request->input('time_start');
        $interview->end = $request->input('time_end');
        $interview->save();
Alessandro Belli's avatar
Alessandro Belli committed
135
        Files::storeSortingScreenshot($request, $study, $interview->id, $name);
ZeMKI's avatar
ZeMKI committed
136
137
138
139
140
        $this->SaveTokenValues($request, $interview);
        Answer::saveResultQuestions($request, $interview);
        Study::removeUpdatePermission($study);
        return response()->json('Interview Saved!', 200);
    }
ZeMKI's avatar
ZeMKI committed
141

ZeMKI's avatar
ZeMKI committed
142
143
144
145
146
147
    /**
     * @param Request   $request
     * @param Interview $interview
     */
    private function SaveTokenValues(Request $request, Interview $interview): void
    {
Alessandro Belli's avatar
Alessandro Belli committed
148
149
150
151
152
153
        foreach ($request->input('sorting') as $sorting) {
            foreach ($sorting['tokens'] as $token) {
                $token['valutation']['position'] = $token['position'];
                if (isset($token['percentagePosition'])) {
                    $token['valutation']['percentagePosition'] = $token['percentagePosition'];
                }
Alessandro Belli's avatar
Alessandro Belli committed
154
155
156
                foreach ($token['valutation']['classifiers'] as $key => $classifier) {
                    unset($token['valutation']['classifiers'][$key]['base64']);
                }
Alessandro Belli's avatar
Alessandro Belli committed
157
                $interview->tokens()->attach($token['id'], ['interview_id' => $interview->id, 'sorting_id' => 1, 'valutation' => json_encode($token['valutation'])]);
158
            }
Laravel Shift's avatar
Laravel Shift committed
159
160
        }
    }
161

Alessandro Belli's avatar
Alessandro Belli committed
162
    /**
Alessandro Belli's avatar
Alessandro Belli committed
163
     * @param Interview $interview
ZeMKI's avatar
ZeMKI committed
164
     * @param Request   $request
Alessandro Belli's avatar
Alessandro Belli committed
165
166
167
     * @return ResponseFactory|Response
     * @throws Exception
     */
Alessandro Belli's avatar
Alessandro Belli committed
168
    public function destroy(Interview $interview, Request $request)
Alessandro Belli's avatar
Alessandro Belli committed
169
    {
ZeMKI's avatar
ZeMKI committed
170
        if (!auth()->user()->can('delete-interviews', $interview->study->id)) return response('You are not authorized to delete this study.', 403);
Alessandro Belli's avatar
Alessandro Belli committed
171
        $id = $interview->id;
172
        $interview->files()->delete();
Alessandro Belli's avatar
Alessandro Belli committed
173
174
175
176
177
178
179
        $interview->answers()->detach();
        $interview->answers()->delete();
        $interview->tokens()->detach();
        $interview->tokens()->delete();
        $interview->delete();
        File::delete($interview->sorting_screenshot);
        $interview->delete();
Alessandro Belli's avatar
Alessandro Belli committed
180
        auth()->user()->addAction('delete interview', $request->url(), 'user deleted interview with id ' . $id);
181
        return response()->json('interview deleted', 200);
Alessandro Belli's avatar
Alessandro Belli committed
182
    }
Alessandro Belli's avatar
Alessandro Belli committed
183

ZeMKI's avatar
ZeMKI committed
184
185
186
187
    /**
     * @param Interview $interview
     * @return Response|BinaryFileResponse
     */
Alessandro Belli's avatar
Alessandro Belli committed
188
189
    public function export(Interview $interview)
    {
190
191
        if (!auth()->user()->can('read-studies', $interview->study_id)) abort(403, "You are not authorized to download these data.");
        return (new InterviewTokenExport($interview->id))->download($interview->interviewed . ' tokens.xlsx');
Alessandro Belli's avatar
Alessandro Belli committed
192
    }
ZeMKI's avatar
ZeMKI committed
193
194
195
196
197
198

    public function done()
    {
        return view('interview.done');

    }
ZeMKI's avatar
ZeMKI committed
199
}