Commit 7974ef56 authored by ZeMKI's avatar ZeMKI
Browse files

New Roles Structure + New Cards in Homepage + Optimization

This big change brings new role structure, similar to Metag-Analyze.
Instructions will be followed to bring this to Production.
The new cards in the homepage follow a design principle to have a more compact, area driven and design friendly style. The interview tab is now changed to "Manage >>" to include user management and (future) statistical data.
Many libraries are now uninstalled,code is less cluttered, database has less tables therefore performance is increased.
Error pages now include buttons to go homepage and back.
Many translation strings were added.
Updated to Laravel 8.
parent 5f718107
......@@ -6,16 +6,15 @@
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/public" />
<excludeFolder url="file://$MODULE_DIR$/vendor/arietimmerman/laravel-url-shortener" />
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
<excludeFolder url="file://$MODULE_DIR$/storage" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-debugbar" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-dompdf" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-ide-helper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-translation-manager" />
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/binarytorch/larecipe" />
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dealerdirect/phpcodesniffer-composer-installer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
......@@ -28,23 +27,29 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/erusev/parsedown" />
<excludeFolder url="file://$MODULE_DIR$/vendor/erusev/parsedown-extra" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
<excludeFolder url="file://$MODULE_DIR$/vendor/firebase/php-jwt" />
<excludeFolder url="file://$MODULE_DIR$/vendor/friendsofphp/php-cs-fixer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fzaninotto/faker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/auth" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/cloud-core" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/cloud-translate" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/common-protos" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/gax" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/grpc-gcp" />
<excludeFolder url="file://$MODULE_DIR$/vendor/google/protobuf" />
<excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
<excludeFolder url="file://$MODULE_DIR$/vendor/grpc/grpc" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/intervention/image" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jasonmccreary/laravel-test-assertions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/justinrainbow/json-schema" />
<excludeFolder url="file://$MODULE_DIR$/vendor/kkszymanowski/traitor" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/telescope" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
......@@ -52,19 +57,15 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/flysystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/mime-type-detection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/livewire/livewire" />
<excludeFolder url="file://$MODULE_DIR$/vendor/maatwebsite/excel" />
<excludeFolder url="file://$MODULE_DIR$/vendor/maennchen/zipstream-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/complex" />
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/matrix" />
<excludeFolder url="file://$MODULE_DIR$/vendor/maximebf/debugbar" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mnapoli/front-yaml" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mnapoli/silly" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/moontoast/math" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mpociot/documentarian" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mpociot/laravel-apidoc-generator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mpociot/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/php-enum" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
......@@ -81,15 +82,12 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/phenx/php-font-lib" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phenx/php-svg-lib" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-cs-fixer/diff" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-di/invoker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phploc/phploc" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoffice/phpspreadsheet" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpseclib/bcmath_compat" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpseclib/phpseclib" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpstan/phpdoc-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
......@@ -97,10 +95,12 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
......@@ -108,17 +108,20 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/rize/uri-template" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sabberworm/php-css-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/santigarcor/laratrust" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/finder-facade" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
......@@ -137,7 +140,6 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
......@@ -167,9 +169,8 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
<excludeFolder url="file://$MODULE_DIR$/vendor/tanmuhittin/laravel-google-translate" />
<excludeFolder url="file://$MODULE_DIR$/vendor/test/laravel-url-shortener" />
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/fdomdocument" />
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
......@@ -177,8 +178,7 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/voku/portable-ascii" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webpatser/laravel-uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/windwalker/renderer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/windwalker/structure" />
<excludeFolder url="file://$MODULE_DIR$/vendor/yandex/translate-api" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
......
......@@ -3,4 +3,7 @@
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectPlainTextFileTypeManager">
<file url="file://$PROJECT_DIR$/database/migrations/2020_10_09_104102_create_user_studies_table.php" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -11,6 +11,7 @@ use App\Study;
use App\User;
use Illuminate\Http\Request;
use Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;
class AdminController extends Controller
{
......@@ -55,7 +56,7 @@ class AdminController extends Controller
/**
* download current backup
* @return backup
* @return StreamedResponse
*/
public function downloadBackup()
{
......@@ -64,34 +65,13 @@ class AdminController extends Controller
/**
* download yesterday backup
* @return backup
* @return StreamedResponse
*/
public function downloadYesterdayBackup()
{
return Storage::disk('local')->download('backup.old.7z');
}
public function supervisorIndex()
{
return view('admin.supervisor');
}
public function addSupervisor(Request $request)
{
$role = Role::where('id', $request->role)->first();
$user = new User();
$user->email = $request->email;
$user->password = bcrypt($request->password);
$user->save();
$user->attachRole($role);
$createStudyPermission = Permission::where('name', 'create-studies')
->first()->toArray();
$user->supervised_by = $user->id;
$user->save();
$user->attachPermissions($createStudyPermission);
return view('admin.supervisor', ['message' => 'Supervisor added']);
}
public function listForNewsletter()
{
......
......@@ -10,6 +10,7 @@ use Helper;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Validator;
use Illuminate\View\View;
use Spatie\WebhookServer\WebhookCall;
class RegisterController extends Controller
......@@ -60,19 +61,19 @@ class RegisterController extends Controller
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
* @return User|View
*/
protected function create($data)
{
$userexist = User::where('email', '=', $data['email'])->first();
$role = Role::where('name', 'supervisor')->first();
if ($userexist) {
return $this->showRegistrationForm();
}
$role = Role::where('name', 'researcher')->first();
$user = new User();
$user->email = $data['email'];
......@@ -85,11 +86,7 @@ class RegisterController extends Controller
$profile->newsletter = array_key_exists('newsletter',$data) ? config('enums.newsletter_status.SUBSCRIBED') : config('enums.newsletter_status.NOT SUBSCRIBED');
$profile->save();
$createStudyPermission = Permission::where('name', 'create-studies')
->first();
$user->supervised_by = $user->id;
$user->attachPermissions([$createStudyPermission]);
$user->attachRole($role);
$user->roles()->sync($role);
if (!App::environment('local')) {
WebhookCall::create()
......
......@@ -26,7 +26,8 @@ class HomeController extends Controller
*/
public function index()
{
$data['studies'] = Auth::user()->studies;
$data['studies'] = Auth::user()->studies()->with('sortings')->get();
$data['invited_studies'] = Auth::user()->invites;
if (auth()->user()->profile()->exists())
{
$data['newsletter'] = Auth::user()->profile->newsletter === config('enums.newsletter_status.NOT DECIDED');
......@@ -35,6 +36,7 @@ class HomeController extends Controller
$profile = auth()->user()->addProfile(auth()->user());
$data['newsletter'] = Auth::user()->profile->newsletter === config('enums.newsletter_status.NOT DECIDED');
}
return view('home', $data);
}
......
......@@ -55,12 +55,13 @@ class InterviewController extends Controller
*/
public function create(Request $request)
{
if(auth()->check()) $this->authorize([Interview::class, $request->input('study')]);
$study = Study::where('id', '=', $request->input('study'));
if(auth()->check()) $this->authorize([Interview::class, $study->first()]);
/** Extract method FORMATQUESTIONSANSWERS */
$this->FormatQuestionsAndAnswers($request, $returnQuestions);
$data['questions'] = $returnQuestions;
$data['study'] = Study::where('id', '=', $request->input('study'))->with('sortings')->first();
$data['study'] = $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;
$data['tokens'] = $data['study']->available_tokens;
......@@ -137,7 +138,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);
}
......@@ -169,7 +170,11 @@ class InterviewController extends Controller
*/
public function destroy(Interview $interview, Request $request)
{
if (!auth()->user()->can('delete-interviews', $interview->study->id)) return response()->json('You are not authorized to delete this study.', 403);
if (auth()->user()->notOwnerNorInvited($interview->study))
{
return response()->json(__('You are not authorized to delete this interview.'), 403);
}
$id = $interview->id;
$interview->files()->delete();
$interview->answers()->detach();
......@@ -189,7 +194,10 @@ class InterviewController extends Controller
*/
public function export(Interview $interview)
{
if (!auth()->user()->can('read-studies', $interview->study_id)) abort(403, "You are not authorized to download these data.");
if (auth()->user()->notOwnerNorInvited($interview->study))
{
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');
}
......
......@@ -3,7 +3,9 @@
namespace App\Http\Controllers;
use App\Answer;
use App\Mail\VerificationEmail;
use App\Permission;
use App\Project;
use App\Question;
use App\Role;
use App\Sorting;
......@@ -21,17 +23,56 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\View\View;
use Spatie\WebhookServer\WebhookCall;
class StudyController extends Controller
{
protected const UPDATESTRING = 'update';
public function show(Study $study)
{
if (auth()->user()->notOwnerNorInvited($study)) abort(403, "You are not authorized to see this content.");
$data['interviews'] = $study->interviews()->get();
$data['invites'] = $study->invited;
$data['publicInterviews'] = collect(DB::select('
select study_interview_public_url.id,
art_urls.id as url_id,
art_urls.url as url,
first_opened_at,
submitted_at,
code
from art_urls
inner join study_interview_public_url
on art_urls.url like CONCAT(\'%\',study_interview_public_url.id,\'%\')
where study_id = :study', ['study' => $study->id]));
foreach ($data['publicInterviews'] as $publicInterview)
{
$publicInterview->shorturl = url('','short')."=".$publicInterview->code;
$publicInterview->url = (\App\Helpers\Helper::get_string_between($publicInterview->url,"&interviewed=","&t") == "") ? "Name not provided" : Helper::get_string_between($publicInterview->url,"&interviewed=","&t");
}
$data['study'] = $study;
foreach ($data['interviews'] as $interview)
{
$interview['author'] = User::where('id', $interview['author'])->first()->email ?? $interview['author'];
}
return view('study.show', $data);
}
public function create(Request $request)
{
if (Auth::user()->hasReachMaxNumberOfStudies())
if (session('hasReachMaxNumberOfStudies'))
{
auth()->user()->addAction('trying to create a study', $request->url(), 'Max numbers of studies reached for user ' . auth()->user()->email);
abort(403, 'You reached the max number of studies');
auth()->user()->addAction('Trying to create a study', $request->url(), 'Max numbers of studies reached for user ' . auth()->user()->email);
abort(403, __('You reached the max number of studies'));
}
// if(!Auth::user()->cancreatestudies())abort(403,'You cannot create studies');
$data['isedit'] = 'false';
......@@ -62,7 +103,7 @@ class StudyController extends Controller
}
}
$copy->save();
$this->saveUserPermissions($copy, Auth::user());
//$this->saveUserPermissions($copy, Auth::user());
return response('study duplicated', 200);
}
......@@ -106,21 +147,6 @@ class StudyController extends Controller
}
}
/**
* @param Study $newstudy
*/
private function saveUserPermissions(Study $newstudy, $user): void
{
$userrole = Role::where('name', $user->listRoles()[0])->first();
$user->attachRole($userrole, $newstudy);
$allPermissions = Permission::where('name', 'read-studies')
->orWhere('name', 'update-studies')
->orWhere('name', 'delete-studies')
->orWhere('name', 'like', '%interviews')
->get()->toArray();
$user->attachPermissions($allPermissions, $newstudy);
}
public function store(Request $request, $dummy = false)
{
if ($dummy != false)
......@@ -139,7 +165,7 @@ class StudyController extends Controller
$newStudy->user_id = $userForStudy->id;
$newStudy->save();
Sorting::store($request, $newStudy);
$this->saveUserPermissions($newStudy, $userForStudy);
// $this->saveUserPermissions($newStudy, $userForStudy);
$this->saveTokens($newStudy, $request, $token);
$presortQuestions = $request->presort['questions'];
$postSortQuestions = $request->postsort['questions'];
......@@ -159,11 +185,12 @@ class StudyController extends Controller
public function saveTokens(Study $study, Request $request, &$token): void
{
if($request->get('sorting')['tokens']){
foreach ($request->get('sorting')['tokens'] as $tokenToSave)
if ($request->get('sorting')['tokens'])
{
Token::store($tokenToSave, $study);
}
foreach ($request->get('sorting')['tokens'] as $tokenToSave)
{
Token::store($tokenToSave, $study);
}
}
}
......@@ -307,6 +334,7 @@ class StudyController extends Controller
*/
public function removeTokensFromStudy(Study $study): void
{
// @todo: delete files as well as tokens.
$available_tokens = $study->available_tokens()->pluck('tokens.id')->toArray();
foreach ($available_tokens as $tokensToDelete)
{
......@@ -317,18 +345,17 @@ class StudyController extends Controller
}
/**
* @param Study $study
* @param Study $study
* @param Request $request
* @return ResponseFactory|Response
* @throws Exception
*/
public function destroy(Study $study, Request $request)
{
if (!auth()->user()->hasRole(['admin', 'supervisor']))
if (auth()->user()->isNot($study->creator()))
{
abort(403, 'You are not allowed to edit this study');
}
if (!auth()->user()->can('delete-studies', $study->id)) return response('You are not authorized to delete this study.', 403);
foreach ($study->interviews as $interview)
{
File::delete($interview->sorting_screenshot);
......@@ -371,4 +398,55 @@ class StudyController extends Controller
auth()->user()->addAction('delete all studies by user', $request->url(), 'user deleted studies for the user ' . $user->email);
return response()->json(['message' => 'Studies Deleted!'], 200);
}
/**
* @param Request $request
* @return JsonResponse
*/
public function inviteUser(Request $request)
{
$study = Study::where('id', $request->input('study'))->first();
$user = User::where('email', '=', $request->email)->first();
if (!$user)
{
$user = new User();
$user->email = $request->email;
$user->password = Helper::random_str(60);
$user->password_token = Helper::random_str(30);
$user->save();
$profile = $user->addProfile($user);
Mail::to($user->email)->send(new VerificationEmail($user, $request->emailtext ? $request->emailtext : config('utilities.emailDefaultText')));
$role = Role::where('name', '=', 'researcher')->first();
$user->roles()->sync($role);
if (!App::environment('local')) {
WebhookCall::create()
->url('https://chat.zemki.uni-bremen.de/hooks/Jj3dDY2KzSFDS2kxZ/SvbmjdswXTASAXxC2GfgfTpFooK5Eo4kFBGPyDRrtsWmgED3')
->payload(['text' => 'User '.$data['email'].' has registered on Mesort. We have a total of '.User::all()->count().' users!'])
->useSecret('Jj3dDY2KzSFDS2kxZ/SvbmjdswXTASAXxC2GfgfTpFooK5Eo4kFBGPyDRrtsWmgED3')
->dispatch();
}
}
if($user->is($study->creator())) return response()->json(['message' => __('You can\'t invite who created the study.!')], 200);
$study->invited()->syncWithoutDetaching($user->id);
return response()->json(['user' => $user, 'message' => __('User was invited!')], 200);
}
public function removeFromStudy(Request $request)
{
if(!auth()->user()->is(Study::find($request->input('study'))->creator())) return response()->json(['message' => __('Not authorized!')], 403);
$user = User::where('email', '=', $request->email)->first();
if ($user)
{
$user->invites()->detach($request->input('study'));
return response()->json(['message' => __('User was removed from the Study!')], 200);
} else
{
return response()->json(['message' => __("The user doesn't exist!")], 403);
}
}
}
......@@ -10,39 +10,10 @@ use Illuminate\Support\Facades\DB;
class StudyInterviewController extends Controller
{
public function index(Study $study)
{
if (!auth()->user()->can('read-studies', $study->id)) abort(403, "You are not authorized to see this content.");
$data['interviews'] = $study->interviews()->get();
$data['publicInterviews'] = collect(DB::select('
select study_interview_public_url.id,
art_urls.id as url_id,
art_urls.url as url,
first_opened_at,
submitted_at,
code
from art_urls
inner join study_interview_public_url
on art_urls.url like CONCAT(\'%\',study_interview_public_url.id,\'%\')
where study_id = :study', ['study' => $study->id]));
foreach ($data['publicInterviews'] as $publicInterview)
{
$publicInterview->shorturl = url('','short')."=".$publicInterview->code;
$publicInterview->url = (Helper::get_string_between($publicInterview->url,"&interviewed=","&t") == "") ? "Name not provided" : Helper::get_string_between($publicInterview->url,"&interviewed=","&t");
}
$data['study'] = $study;
foreach ($data['interviews'] as $interview)
{
$interview['author'] = User::where('id', $interview['author'])->first()->email ?? $interview['author'];
}
return view('interview.index', $data);
}
public function exportall(Study $study)
{
if (!auth()->user()->can('read-studies', $study->id)) abort(403, "You are not authorized to download these data.");
if (auth()->user()->notOwnerNorInvited($study)) abort(403, "You are not authorized to download these data.");
$headings = $this->getHeadings($study);
return (new AllInterviewTokenExport($study->id, $headings))->download('Interviews from study' . $study->name . '.xlsx');
......
......@@ -43,83 +43,6 @@ class UserController extends Controller
return response()->json($data, 200);
}
public function newuserpart()
{
// get all the studies and related users
// STUDIES
// id - name - research question - users
// ---
// get the unique value from the users to display them below he study section