Commit 0ea60742 authored by ZeMKI's avatar ZeMKI
Browse files

Save Interview and Show sorting on postsort

* now user can see the sorting in the post sort questions (also multiple sortings in circle and network sorting).
* values saved in the database and correctly shown in the export.
parent 17d1811f
......@@ -19,29 +19,38 @@ class InterviewTokenExport implements FromCollection, WithMapping, WithHeadings
*/
private $head;
private $id;
private $sorting;
/**
* InterviewTokenExport constructor.
* @param $id
* @param array $headings
*/
public function __construct($id, $headings = [])
public function __construct($id, $headings = [], $sorting)
{
$this->id = $id;
$this->head = $headings;
$this->sorting = $sorting;
}
public function headings(): array
{
$columnNames = ["#"];
array_push($columnNames, "token_name");
array_push($columnNames, "circle");
array_push($columnNames, "distance from center (pixels)");
array_push($columnNames, "sorting number");
array_push($columnNames, "position (pixels)");
array_push($columnNames, "% percentage position");
array_push($columnNames, "Interviewee Name");
array_push($columnNames, "classifiers");
if($this->sorting == 1 || $this->sorting == 2)
{
array_push($columnNames, "circle");
array_push($columnNames, "distance from center (pixels)");
array_push($columnNames, "sorting number");
array_push($columnNames, "position (pixels)");
array_push($columnNames, "% percentage position");
array_push($columnNames, "Interviewee Name");
array_push($columnNames, "classifiers");
}else{
array_push($columnNames, "position column/row");
array_push($columnNames, "Interviewee Name");
}
foreach ($this->head as $column)
{
array_push($columnNames, $column);
......@@ -69,16 +78,24 @@ class InterviewTokenExport implements FromCollection, WithMapping, WithHeadings
$tempValuesArray = [];
$tempValuesArray["#"] = $token->token_id;
$tempValuesArray["token_name"] = Token::where('id', $token->token_id)->first()->name;
$tempValuesArray["circle"] = $token->valutation->circle;
$tempValuesArray["distance from center (pixels)"] = $token->valutation->distance;
$tempValuesArray["sorting number"] = $token->valutation->sorting;
$tempValuesArray["position (pixels)"] = $position;
$tempValuesArray["% percentage position"] = $percentagePosition;
if($token->interview->study->sortings[0]->id == 3)
{
$tempValuesArray["position column/row"] = $position;
}else{
$tempValuesArray["circle"] = $token->valutation->circle;
$tempValuesArray["distance from center (pixels)"] = $token->valutation->distance;
$tempValuesArray["sorting number"] = $token->valutation->sorting;
$tempValuesArray["position (pixels)"] = $position;
$tempValuesArray["% percentage position"] = $percentagePosition;
$tempValuesArray["classifiers"] = $classifiers;
}
$tempValuesArray["interviewee name"] = $token->interview->interviewed;
$tempValuesArray["classifiers"] = $classifiers;
if ($token->interview->study->sortings[0]->id === 2)
{
$tempValuesArray['section number'] = strval($token->valutation->section);
$tempValuesArray['section name'] = $token->valutation->sectionName;
}
......@@ -89,9 +106,10 @@ class InterviewTokenExport implements FromCollection, WithMapping, WithHeadings
* @param $token
* @return bool
*/
private function invalidData($interview): bool
private function invalidData($token): bool
{
return !is_object($interview->valutation->position) && $interview->valutation->position == 0 && $interview->valutation->distance == 0 && $interview->valutation->circle == 0 && $interview->study->sortings[0]->id === 2;
return !is_object($token->valutation->position) && $token->valutation->position == 0 && $token->valutation->distance == 0 && $token->valutation->circle == 0 && $token->interview->study->sortings[0]->id === 2;
}
/**
......
......@@ -17,13 +17,11 @@ use File;
use Helper;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use Storage;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class InterviewController extends Controller
......@@ -31,7 +29,7 @@ class InterviewController extends Controller
public function show(Interview $interview)
{
$this->authorize($interview);
$data['breadcrumb'] = ['Home','Study',$interview->study->name,$interview->interviewed == __("Name not provided") ? "Interview id ".$interview->id : __("Interview of")." ".$interview->interviewed];
$data['breadcrumb'] = ['Home', 'Study', $interview->study->name, $interview->interviewed == __("Name not provided") ? "Interview id " . $interview->id : __("Interview of") . " " . $interview->interviewed];
$data['interview'] = $interview;
$data['screenshots'] = [];
$data['sortingtoken'] = $interview->tokens;
......@@ -39,11 +37,13 @@ class InterviewController extends Controller
$data['createdtokens'] = Token::formatForEdit($interview->tokens()->where('tokens.author', '=', 0)->get());
$data['study'] = $interview->study;
$data['questions'] = $interview->study->questions;
$data['sorting'] = $interview->study->sortings[0];
$data['author'] = User::where('id', $interview->author)->first()->email ?? $interview->author;
Answer::assignAnswersToQuestion($interview, $data);
Sorting::getSortingInfo($interview->study, $data);
Interview::getSortingImages($interview, $data);
return view('interview.view', $data);
}
......@@ -57,8 +57,7 @@ class InterviewController extends Controller
public function create(Request $request)
{
$study = Study::where('id', '=', $request->input('study'));
if(auth()->check()) $this->authorize([Interview::class, $study->first()]);
if (auth()->check()) $this->authorize([Interview::class, $study->first()]);
/** Extract method FORMATQUESTIONSANSWERS */
$this->FormatQuestionsAndAnswers($request, $returnQuestions);
$data['questions'] = $returnQuestions;
......@@ -94,13 +93,16 @@ class InterviewController extends Controller
group by qid,q,type';
$questions = DB::select(DB::raw($query));
$returnQuestions['presort'] = $returnQuestions['postsort'] = [];
foreach ($questions as $question) {
foreach ($questions as $question)
{
$question->answer = json_decode('[' . $question->answer . ']');
$question->answer['ids'] = explode(',', $question->answerids);
if ($question->type === 'presort') {
if ($question->type === 'presort')
{
array_push($returnQuestions['presort'], $question);
}
if ($question->type === 'postsort') {
if (strpos($question->type, 'postsort') != -1)
{
array_push($returnQuestions['postsort'], $question);
}
}
......@@ -112,11 +114,14 @@ class InterviewController extends Controller
private function GetTokensForInterview(&$data): void
{
$TokensCount = count($data['tokens']);
for ($i = 0; $i < $TokensCount; $i++) {
if (strpos($data['tokens'][$i]['image_path'], 'presets') !== false) {
for ($i = 0; $i < $TokensCount; $i++)
{
if (strpos($data['tokens'][$i]['image_path'], 'presets') !== false)
{
$path = $data['tokens'][$i]['image_path'];
$data['tokens'][$i]['image_path'] = mb_convert_encoding($path, 'HTML-ENTITIES', 'UTF-8');
} else {
} else
{
$path = storage_path('app/' . $data['tokens'][$i]['image_path']);
$data['tokens'][$i]['image_path'] = decrypt(file_get_contents($path));
}
......@@ -126,9 +131,7 @@ class InterviewController extends Controller
public function store(Request $request)
{
$study = Study::where('id', '=', $request->input('study'))->first();
$author = auth()->check() ? Auth::user()->id : 'From public url.';
$interview = new Interview();
$interview->study_id = $study->id;
$interview->author = $author;
......@@ -139,7 +142,7 @@ class InterviewController extends Controller
Files::storeSortingScreenshot($request, $study, $interview->id, $name);
$this->SaveTokenValues($request, $interview);
Answer::saveResultQuestions($request, $interview);
// Study::removeUpdatePermission($study);
// Study::removeUpdatePermission($study);
return response()->json('Interview Saved!', 200);
}
......@@ -149,13 +152,17 @@ class InterviewController extends Controller
*/
private function SaveTokenValues(Request $request, Interview $interview): void
{
foreach ($request->input('sorting') as $sorting) {
foreach ($sorting['tokens'] as $token) {
foreach ($request->input('sorting') as $sorting)
{
foreach ($sorting['tokens'] as $token)
{
$token['valutation']['position'] = $token['position'];
if (isset($token['percentagePosition'])) {
if (isset($token['percentagePosition']))
{
$token['valutation']['percentagePosition'] = $token['percentagePosition'];
}
foreach ($token['valutation']['classifiers'] as $key => $classifier) {
foreach ($token['valutation']['classifiers'] as $key => $classifier)
{
unset($token['valutation']['classifiers'][$key]['base64']);
}
$interview->tokens()->attach($token['id'], ['interview_id' => $interview->id, 'sorting_id' => 1, 'valutation' => json_encode($token['valutation'])]);
......@@ -175,7 +182,6 @@ class InterviewController extends Controller
{
return response()->json(__('You are not authorized to delete this interview.'), 403);
}
$id = $interview->id;
$interview->files()->delete();
$interview->answers()->detach();
......@@ -200,19 +206,17 @@ class InterviewController extends Controller
abort(403, "You are not authorized to download these data.");
}
$headings = $this->getHeadings($interview->study);
return (new InterviewTokenExport($interview->id, $headings))->download($interview->interviewed . ' tokens.xlsx');
return (new InterviewTokenExport($interview->id, $headings, $interview->study->sortings[0]->id))->download($interview->interviewed . ' tokens.xlsx');
}
public function getHeadings($study)
{
if($study->sortings[0]->id == 2)
if ($study->sortings[0]->id == 2)
{
return ["section number","section name"];
}else return [];
return ["section number", "section name"];
} else return [];
}
/**
......@@ -221,6 +225,5 @@ class InterviewController extends Controller
public function done()
{
return view('interview.done');
}
}
......@@ -221,6 +221,7 @@ class StudyController extends Controller
$question = new Question();
$question->question = $questionToSave['question'];
$question->detail = $questions[0]['type'];
if(array_key_exists('canShowSorting',$questionToSave) && $questionToSave['canShowSorting']) $question->detail .= '|showsorting';
$question->study_id = $study->id;
$question->save();
$this->saveAnswers($questionToSave, $question);
......
......@@ -165,13 +165,19 @@ export default {
if(!_.isEmpty(this.selectedToken))
{
console.log(this.selectedToken)
// @todo if I put the token in a position that is occupied by another token remove the position from the token array and assign that to the new moved token
console.log(_.find(this.tokens, (o) => o.id === this.selectedToken.id))
let tokenToChange = _.find(this.tokens, (o) => o.id === this.selectedToken.id);
console.log(tokenToChange)
this.arrayOfQsort[key][n] = this.selectedToken;
this.$store.commit('updateselectedtoken',{});
this.$forceUpdate()
tokenToChange.position = [key,Math.abs(n-(this.arrayOfQsort[key].length-1))]
}else{
}
},
......
......@@ -1166,6 +1166,16 @@
trans('Scale values')
}}
</label>
<label
class="checkbox">
<input
v-model="q.canShowSorting"
type="checkbox"
>
{{
trans('Show sorting')
}}
</label>
</div>
......@@ -1426,7 +1436,7 @@ export default {
}, postsort: {
number: 1, questions: [
{
question: '', isopen: false, ismultiple: true, isonechoice: false, isscale: false, scalemin: 0, scalemax: 100, numberofanswer: 2, minlabel: '', maxlabel: '', answers: [],
question: '', canShowSorting: false, isopen: false, ismultiple: true, isonechoice: false, isscale: false, scalemin: 0, scalemax: 100, numberofanswer: 2, minlabel: '', maxlabel: '', answers: [],
},
],
......
......@@ -5,202 +5,212 @@
<div class="w-2/3 mx-auto">
<h1 class="font-bold text-4xl">{{$study->name}}</h1>
<p class="text-base">
<p class="font-bold inline">{{__('Interview done by')}}:</p> {{$author}}<br>
<p class="font-bold inline">{{__('Interviewed')}}: </p>{{$interview->interviewed}} <br>
<p class="font-bold inline">{{__('From')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->start))}}
- <p class="font-bold inline">{{__('To')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->end))}}
</p>
<hr>
<h5 class="text-sm font-bold">
{{$study->description}}
</h5>
<h1 class="font-bold text-4xl uppercase ">{{__('Sorting(s)')}}</h1>
<?php $i = 1 ?>
<div class="block mt-2">
<b-tabs type="is-toggle" expanded>
@foreach($screenshots as $screenshot)
<b-tab-item :label="trans('Sorting')+' '+{{$i}}" icon="google-photos"><a href="
<h1 class="font-bold text-4xl">{{$study->name}}</h1>
<p class="text-base">
<p class="font-bold inline">{{__('Interview done by')}}:</p> {{$author}}<br>
<p class="font-bold inline">{{__('Interviewed')}}: </p>{{$interview->interviewed}} <br>
<p class="font-bold inline">{{__('From')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->start))}}
- <p class="font-bold inline">{{__('To')}}: </p>{{date('d.m.Y H:i:s', strtotime($interview->end))}}
</p>
<hr>
<h5 class="text-sm font-bold">
{{$study->description}}
</h5>
<h1 class="font-bold text-4xl uppercase ">{{__('Sorting(s)')}}</h1>
<?php $i = 1 ?>
<div class="block mt-2 w-full h-auto">
<b-tabs type="is-toggle" expanded>
@foreach($screenshots as $screenshot)
<b-tab-item :label="trans('Sorting')+' '+{{$i}}" icon="google-photos"><a href="
{{url('/interview/'.$interview->id.'/sorting/'.$screenshot['type'].'/show')}}"
target="_blank"><img
src="{{$screenshot['image']}}"/></a>
</b-tab-item>
<?php $i++; ?>
@endforeach
</b-tabs>
target="_blank">
<img src="{{$screenshot['image']}}" alt="sorting" class="w-full h-auto"/></a>
</b-tab-item>
<?php $i++; ?>
@endforeach
</b-tabs>
</div>
@forelse($createdtokens->unique('id') as $token)
<h1 class="text-2xl font-bold">{{__('Created Tokens')}}</h1>
<div class="block ml-2">
<img src="{{$token->image_path}}" alt="token created" class="block w-10"/>
{{$token->name}} - {{__('Created in Sorting')}}
: {{ json_decode($token->pivot->valutation)->sorting}}
</div>
@forelse($createdtokens->unique('id') as $token)
<h1 class="text-2xl font-bold">{{__('Created Tokens')}}</h1>
<div class="block ml-2">
<img src="{{$token->image_path}}" alt="token created" class="block w-10"/>
{{$token->name}} - {{__('Created in Sorting')}}
: {{ json_decode($token->pivot->valutation)->sorting}}
</div>
@empty
@empty
@if($study->sortings[0]->id !== 3)
<h1 class="text-2xl font-bold">{{__('0 Created Tokens')}}</h1>
@else
@foreach($sortingtoken as $token)
@if(is_array(json_decode($token->getOriginal()['pivot_valutation'])->position))
{{$token->name}} - {{__('Position')}}: {{implode(",",json_decode($token->getOriginal()['pivot_valutation'])->position)}} <br>
@else
{{$token->name}} - {{__('No Position Specified')}}<br>
@endif
@endforeach
@endif
@endforelse
@endforelse
<div class="w-1/6 p-2 bg-blue-100 text-center uppercase text-black my-4">{{__('Available answer')}}</div>
<div class="w-1/6 p-2 bg-blue-500 text-center uppercase text-white">{{__('Chosen answer')}}</div>
<div class="my-2">
<h1 class="font-bold text-4xl uppercase">{{__('Pre-Sort Phase')}}</h1>
<div class="my-2">
<h1 class="font-bold text-4xl uppercase">{{__('Pre-Sort Phase')}}</h1>
@foreach($questions as $q)
@foreach($questions as $q)
@if(strpos($q->detail,"presort") > -1)
<h3 class="text-2xl bg-blue-100 mb-2 mt-2 p-2 text-center">{{$q->question}}</h3>
<?php
$emptyopen = true;
?>
@foreach($q->answers as $a)
@if($a->answer['answer'] != "" && $a->answer['type'] != "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->answer['answer']}}</div>
<div
class="text-sm w-auto inline-block">{{$a->answer['type']}} {{__('answer')}}</div>
<br>
@if($q->detail == "presort")
<h3 class="text-2xl bg-blue-100 mb-2 mt-2 p-2 text-center">{{$q->question}}</h3>
@elseif($a->answer['type'] == "open")
<?php
$emptyopen = true;
$emptyopen = false;
?>
@foreach($q->answers as $a)
@if($a->answer['answer'] != "" && $a->answer['type'] != "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->answer['answer']}}</div>
<div
class="text-sm w-auto inline-block">{{$a->answer['type']}} {{__('answer')}}</div>
<br>
@elseif($a->answer['type'] == "open")
<?php
$emptyopen = false;
?>
<div
class="bg-blue-500 text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->pivot->result}}</div>
<div
class="bg-white text-black text-sm w-auto inline-block"> {{__('Open answer')}}</div>
<br>
@elseif($a->answer['type'] == "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->pivot->result}}</div>
<div class="bg-white text-black text-sm"> {{__('Scale answer')}}</div>
<br>
@endif
@endforeach
@foreach($q->available_answers as $available)
@if($available['type']== "multi" || $available['type']== "onechoice")
<div
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{$available['answer']}}</div>
@elseif($available['type']== "scale")
<br>
<br>
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{__('Minimum value')}} {{$available['answer']->min}}</p>
<br>
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{__('Max value')}} {{$available['answer']->max}}</p>
@else
<br>
@if($emptyopen)
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2"> {{__('Empty open answer')}} </p>
@else
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2"> {{__('Open Answer')}}</p>
@endif
@endif
@endforeach
<div
class="bg-blue-500 text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->pivot->result}}</div>
<div
class="bg-white text-black text-sm w-auto inline-block"> {{__('Open answer')}}</div>
<br>
@elseif($a->answer['type'] == "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->pivot->result}}</div>
<div class="bg-white text-black text-sm"> {{__('Scale answer')}}</div>
<br>
@endif
@endforeach
@foreach($q->available_answers as $available)
@if($available['type']== "multi" || $available['type']== "onechoice")
<div
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{$available['answer']}}</div>
@elseif($available['type']== "scale")
<br>
<br>
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{__('Minimum value')}} {{$available['answer']->min}}</p>
<br>
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block">{{__('Max value')}} {{$available['answer']->max}}</p>
@else
<br>
@if($emptyopen)
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2"> {{__('Empty open answer')}} </p>
@else
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2"> {{__('Open Answer')}}</p>
@endif
@endif
@endforeach
</div>
<h1 class="font-bold text-4xl uppercase ">{{__('Post-Sort Phase')}}</h1>
@endif
@foreach($questions as $q)
@if($q->detail == "postsort")
<h3 class="text-2xl bg-blue-100 mb-2 mt-2 p-2 text-center">{{$q->question}}</h3>
<?php
$emptyopen = true;
?>
@foreach($q->answers as $a)
@if($a->answer['answer'] != "" && $a->answer['type'] != "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block my-2">{{$a->answer['answer']}}</div>
<div
class="bg-white text-black text-sm">{{$a->answer['type']}} {{__('answer')}}</div>
<br>
@elseif($a->answer['type'] == "open")
<?php
$emptyopen = false;
?>
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block">{{$a->pivot->result}}</div>
<div
class="bg-white text-black text-sm w-auto inline-block"> {{__('Open answer')}}</div>
<br>
@elseif($a->answer['type'] == "scale")
<div
class="text-white p-2 text-xl bg-blue-500 w-auto inline-block">{{$a->pivot->result}}</div>
<div
class="bg-white text-black text-sm w-auto inline-block"> {{__('Scale answer')}}</div>
<br>
@endif
@endforeach
@foreach($q->available_answers as $available)
@if($available['type']== "multi" || $available['type']== "onechoice")
<div
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2">{{$available['answer']}}</div>
@elseif($available['type']== "scale")
<p
class="bg-blue-100 text-black p-2 text-sm w-auto inline-block my-2">{{__('Minimum value')}} {{$available['answer']->min}}</p>
<br>
<p