From 7f0d18fcb432bfe9bc37bf7190d8603aea36328b Mon Sep 17 00:00:00 2001 From: muni Date: Tue, 25 Jul 2023 19:12:37 +0530 Subject: [PATCH] Quiz start logic --- .gitignore | 1 + app/Console/Kernel.php | 1 + app/Http/Controllers/QuizController.php | 34 +++- app/Models/QuizResult.php | 11 ++ app/Providers/AppServiceProvider.php | 5 +- app/Providers/TelescopeServiceProvider.php | 65 ++++++ composer.json | 5 +- composer.lock | 73 ++++++- config/telescope.php | 187 ++++++++++++++++++ .../views/quizzes/incomplete-quiz.blade.php | 65 ++++++ resources/views/quizzes/index.blade.php | 2 +- routes/web.php | 1 + 12 files changed, 441 insertions(+), 9 deletions(-) create mode 100644 app/Providers/TelescopeServiceProvider.php create mode 100644 config/telescope.php create mode 100644 resources/views/quizzes/incomplete-quiz.blade.php diff --git a/.gitignore b/.gitignore index ecdfa4f..e5b2b25 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /node_modules /public/build /public/hot +/public/vendor /public/storage /storage/*.key /vendor diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e6b9960..5b6694e 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -13,6 +13,7 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule): void { // $schedule->command('inspire')->hourly(); + $schedule->command('telescope:prune')->daily(); } /** diff --git a/app/Http/Controllers/QuizController.php b/app/Http/Controllers/QuizController.php index 73a689d..ba0d4e2 100644 --- a/app/Http/Controllers/QuizController.php +++ b/app/Http/Controllers/QuizController.php @@ -104,20 +104,43 @@ public function store(StoreQuizRequest $request) /** * Display the specified resource. */ - public function start($category_id, $quiz_id) + public function start($category_id, $quiz_id, $quiz_result_id = null) { $quiz = Quiz::findOrFail($quiz_id); - $questions = Question::getQuestions($quiz_id); $user = auth()->user(); + $guest_role = !$user->hasRole([TEACHER, SUPER_ADMIN, STUDENT]); + + + if (!empty($quiz_result_id)) { + $quizResult = QuizResult::with('quiz')->where('user_id', $user->id) + ->where('id', $quiz_result_id) + ->whereNull('answers') + ->first(); - ## Guest - if (!$user->hasRole([TEACHER, SUPER_ADMIN, STUDENT])) { + $questions = json_decode($quizResult->questions); + return view('quizzes.start', compact('questions', 'quizResult', 'quiz')); + } + + $force = request()->has('force'); + $quizResults = QuizResult::with('quiz')->where('user_id', $user->id) + ->where('quiz_id', $quiz_id) + ->whereNull('answers') + ->get(); + + if ( + ($quizResults->count() && $guest_role) || + ($quizResults->count() && !$force) + ) { + return view('quizzes.incomplete-quiz', compact('quizResults', 'category_id', 'quiz_id', 'guest_role', 'force')); + } + + // guest not allowed to attempt more than one pre test + if ($guest_role) { $count = QuizResult::where('user_id', $user->id) ->where('quiz_id', $quiz_id) ->whereNotNull('answers') ->count(); - if ($count) { return redirect()->route('dashboard') ->with('error', __('To access additional tests, kindly upgrade your subscription as you have already used your complimentary tests..')); @@ -125,6 +148,7 @@ public function start($category_id, $quiz_id) } + $questions = Question::getQuestions($quiz_id); $quizResult = QuizResult::create([ 'user_id' => $user->id, 'quiz_id' => $quiz_id, diff --git a/app/Models/QuizResult.php b/app/Models/QuizResult.php index f3219c2..e7f14e7 100644 --- a/app/Models/QuizResult.php +++ b/app/Models/QuizResult.php @@ -12,4 +12,15 @@ class QuizResult extends Model protected $table = 'quiz_results'; protected $fillable = ['user_id', 'quiz_id', 'questions']; + + + public function user() + { + return $this->belongsTo(User::class, 'user_id'); + } + + public function quiz() + { + return $this->belongsTo(Quiz::class, 'quiz_id'); + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..9bd4fc7 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -11,7 +11,10 @@ class AppServiceProvider extends ServiceProvider */ public function register(): void { - // + if ($this->app->environment('local')) { + $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class); + $this->app->register(TelescopeServiceProvider::class); + } } /** diff --git a/app/Providers/TelescopeServiceProvider.php b/app/Providers/TelescopeServiceProvider.php new file mode 100644 index 0000000..d13b001 --- /dev/null +++ b/app/Providers/TelescopeServiceProvider.php @@ -0,0 +1,65 @@ +hideSensitiveRequestDetails(); + + Telescope::filter(function (IncomingEntry $entry) { + if ($this->app->environment('local')) { + return true; + } + + return $entry->isReportableException() || + $entry->isFailedRequest() || + $entry->isFailedJob() || + $entry->isScheduledTask() || + $entry->hasMonitoredTag(); + }); + } + + /** + * Prevent sensitive request details from being logged by Telescope. + */ + protected function hideSensitiveRequestDetails(): void + { + if ($this->app->environment('local')) { + return; + } + + Telescope::hideRequestParameters(['_token']); + + Telescope::hideRequestHeaders([ + 'cookie', + 'x-csrf-token', + 'x-xsrf-token', + ]); + } + + /** + * Register the Telescope gate. + * + * This gate determines who can access Telescope in non-local environments. + */ + protected function gate(): void + { + Gate::define('viewTelescope', function ($user) { + return in_array($user->email, [ + // + ]); + }); + } +} diff --git a/composer.json b/composer.json index ea6b33f..13fbcdb 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "fakerphp/faker": "^1.9.1", "laravel/pint": "^1.0", "laravel/sail": "^1.18", + "laravel/telescope": "^4.15", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^7.0", "phpunit/phpunit": "^10.1", @@ -52,7 +53,9 @@ }, "extra": { "laravel": { - "dont-discover": [] + "dont-discover": [ + "laravel/telescope" + ] } }, "config": { diff --git a/composer.lock b/composer.lock index b6980ec..36330b7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5472c0329b208bac94d14e0d66cdbd18", + "content-hash": "14cdb532c78dcf37cfb7e47ccc6432b6", "packages": [ { "name": "bacon/bacon-qr-code", @@ -6531,6 +6531,77 @@ }, "time": "2023-05-04T14:52:56+00:00" }, + { + "name": "laravel/telescope", + "version": "v4.15.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "5d74ae4c9f269b756d7877ad1527770c59846e14" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/5d74ae4c9f269b756d7877ad1527770c59846e14", + "reference": "5d74ae4c9f269b756d7877ad1527770c59846e14", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0|^10.0", + "php": "^8.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "laravel/octane": "^1.4", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v4.15.2" + }, + "time": "2023-07-13T20:06:27+00:00" + }, { "name": "mockery/mockery", "version": "1.6.2", diff --git a/config/telescope.php b/config/telescope.php new file mode 100644 index 0000000..9a09fda --- /dev/null +++ b/config/telescope.php @@ -0,0 +1,187 @@ + env('TELESCOPE_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | Telescope Path + |-------------------------------------------------------------------------- + | + | This is the URI path where Telescope will be accessible from. Feel free + | to change this path to anything you like. Note that the URI will not + | affect the paths of its internal API that aren't exposed to users. + | + */ + + 'path' => env('TELESCOPE_PATH', 'telescope'), + + /* + |-------------------------------------------------------------------------- + | Telescope Storage Driver + |-------------------------------------------------------------------------- + | + | This configuration options determines the storage driver that will + | be used to store Telescope's data. In addition, you may set any + | custom options as needed by the particular driver you choose. + | + */ + + 'driver' => env('TELESCOPE_DRIVER', 'database'), + + 'storage' => [ + 'database' => [ + 'connection' => env('DB_CONNECTION', 'mysql'), + 'chunk' => 1000, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Master Switch + |-------------------------------------------------------------------------- + | + | This option may be used to disable all Telescope watchers regardless + | of their individual configuration, which simply provides a single + | and convenient way to enable or disable Telescope data storage. + | + */ + + 'enabled' => env('TELESCOPE_ENABLED', true), + + /* + |-------------------------------------------------------------------------- + | Telescope Route Middleware + |-------------------------------------------------------------------------- + | + | These middleware will be assigned to every Telescope route, giving you + | the chance to add your own middleware to this list or change any of + | the existing middleware. Or, you can simply stick with this list. + | + */ + + 'middleware' => [ + 'web', + Authorize::class, + ], + + /* + |-------------------------------------------------------------------------- + | Allowed / Ignored Paths & Commands + |-------------------------------------------------------------------------- + | + | The following array lists the URI paths and Artisan commands that will + | not be watched by Telescope. In addition to this list, some Laravel + | commands, like migrations and queue commands, are always ignored. + | + */ + + 'only_paths' => [ + // 'api/*' + ], + + 'ignore_paths' => [ + 'nova-api*', + ], + + 'ignore_commands' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Telescope Watchers + |-------------------------------------------------------------------------- + | + | The following array lists the "watchers" that will be registered with + | Telescope. The watchers gather the application's profile data when + | a request or task is executed. Feel free to customize this list. + | + */ + + 'watchers' => [ + Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true), + + Watchers\CacheWatcher::class => [ + 'enabled' => env('TELESCOPE_CACHE_WATCHER', true), + 'hidden' => [], + ], + + Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true), + + Watchers\CommandWatcher::class => [ + 'enabled' => env('TELESCOPE_COMMAND_WATCHER', true), + 'ignore' => [], + ], + + Watchers\DumpWatcher::class => [ + 'enabled' => env('TELESCOPE_DUMP_WATCHER', true), + 'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false), + ], + + Watchers\EventWatcher::class => [ + 'enabled' => env('TELESCOPE_EVENT_WATCHER', true), + 'ignore' => [], + ], + + Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true), + + Watchers\GateWatcher::class => [ + 'enabled' => env('TELESCOPE_GATE_WATCHER', true), + 'ignore_abilities' => [], + 'ignore_packages' => true, + 'ignore_paths' => [], + ], + + Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true), + + Watchers\LogWatcher::class => [ + 'enabled' => env('TELESCOPE_LOG_WATCHER', true), + 'level' => 'error', + ], + + Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true), + + Watchers\ModelWatcher::class => [ + 'enabled' => env('TELESCOPE_MODEL_WATCHER', true), + 'events' => ['eloquent.*'], + 'hydrations' => true, + ], + + Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true), + + Watchers\QueryWatcher::class => [ + 'enabled' => env('TELESCOPE_QUERY_WATCHER', true), + 'ignore_packages' => true, + 'ignore_paths' => [], + 'slow' => 100, + ], + + Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true), + + Watchers\RequestWatcher::class => [ + 'enabled' => env('TELESCOPE_REQUEST_WATCHER', true), + 'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64), + 'ignore_http_methods' => [], + 'ignore_status_codes' => [], + ], + + Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true), + Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true), + ], +]; diff --git a/resources/views/quizzes/incomplete-quiz.blade.php b/resources/views/quizzes/incomplete-quiz.blade.php new file mode 100644 index 0000000..2d23590 --- /dev/null +++ b/resources/views/quizzes/incomplete-quiz.blade.php @@ -0,0 +1,65 @@ + + + {{ __('Incomplete Tests') }} + + + + +
+ @if ($guest_role && $force) +
+ To access additional tests, kindly upgrade your subscription as you have already used your complimentary tests.. +
+ @endif + + +
+ + + + + @include('admin.includes.sort-link', ['label' => 'Name', 'attribute' => 'quiz_name']) + + + {{ __('Status') }} + + + {{ __('Actions') }} + + + + + @foreach($quizResults as $quizResult) + + + + + + +
+ Incomplete +
+
+ + + + {{ __('Continue') }} + + + + @endforeach + +
+
+
+
+
OR
+
+ + +
+
\ No newline at end of file diff --git a/resources/views/quizzes/index.blade.php b/resources/views/quizzes/index.blade.php index 7a810f3..1bee3e8 100644 --- a/resources/views/quizzes/index.blade.php +++ b/resources/views/quizzes/index.blade.php @@ -1,6 +1,6 @@ - {{ __('Quizzes') }} + {{ __('Tests') }} @can('quiz create') diff --git a/routes/web.php b/routes/web.php index ac6e01f..a6c18f8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -46,6 +46,7 @@ Route::resource('tests', QuizController::class); Route::get('test/{category_id}/{quiz_id}', [QuizController::class, 'start']); + Route::get('test/{category_id}/{quiz_id}/{quiz_result_id?}', [QuizController::class, 'start']); Route::get('test/{category_id}', [QuizController::class, 'show_quizzes']); // Assign Test