Skip to content

Commit

Permalink
Merge pull request #105 from gloggi/restore-data-from-expired-forms
Browse files Browse the repository at this point in the history
Restore data from expired forms
  • Loading branch information
carlobeltrame authored Jan 1, 2020
2 parents 05368b3 + 0672de1 commit a92da94
Show file tree
Hide file tree
Showing 21 changed files with 230 additions and 26 deletions.
16 changes: 16 additions & 0 deletions app/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace App\Exceptions;

use App\Http\Middleware\RestoreFormDataFromExpiredSession;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
Expand Down Expand Up @@ -46,6 +48,20 @@ public function report(Exception $exception)
*/
public function render($request, Exception $exception)
{
if ($exception instanceof AuthenticationException && $request->method() != 'GET') {
$this->preserveSubmittedFormData($request);
}
return parent::render($request, $exception);
}

/**
* The user submitted a form but wasn't authenticated. Probably the session expired.
* Preserve the form data so it can be restored once the user logs back in.
*
* @param \Illuminate\Http\Request $request
*/
protected function preserveSubmittedFormData($request) {
session()->put(RestoreFormDataFromExpiredSession::KEY, $request->except($this->dontFlash));
session()->flash('alert-warning', __('t.errors.session_expired_try_again'));
}
}
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Kernel extends HttpKernel
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'courseNotArchived' => CourseMustNotBeArchived::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'restoreFormData' => \App\Http\Middleware\RestoreFormDataFromExpiredSession::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
Expand Down
31 changes: 31 additions & 0 deletions app/Http/Middleware/RestoreFormDataFromExpiredSession.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;

class RestoreFormDataFromExpiredSession
{
const KEY = '_restorable_form_data';

/**
* In case the user entered data in a form, but was logged out in the meantime,
* his data is saved in the session when he submits the request. This middleware
* restores that saved form data once the user has logged back in.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (session()->has(self::KEY)) {
session()->now('_old_input', session(self::KEY));
session()->forget(self::KEY);
session()->now('alert-warning', __('t.errors.form_data_restored_please_submit_again'));
}
return $next($request);
}
}
13 changes: 13 additions & 0 deletions resources/js/Components/BlockAndRequirementsInputWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,26 @@
export default {
name: 'BlockAndRequirementsInputWrapper',
props: {
hasOldValues: {
type: Boolean,
default: false
}
},
data: function () {
return {
// If we have old input, ignore the first input event from the block selection component,
// so we don't overwrite the old value of the requirements selection component initially.
ignoreNextBlockUpdateEvent: this.hasOldValues,
requirementsValue: ''
}
},
methods: {
onBlockUpdate (blockObject) {
if (this.ignoreNextBlockUpdateEvent) {
this.ignoreNextBlockUpdateEvent = false
return
}
this.requirementsValue = blockObject.data
}
}
Expand Down
11 changes: 6 additions & 5 deletions resources/js/Components/MultiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default {
name: String,
multiple: Boolean,
noOptions: String,
oldValue: String,
value: String,
options: Array,
submitOnInput: String,
Expand All @@ -34,7 +35,7 @@ export default {
},
data: function() {
return {
currentValue: this.initialValue()
currentValue: this.selectedOptions(this.oldValue !== undefined ? this.oldValue : this.value)
}
},
computed: {
Expand All @@ -50,11 +51,11 @@ export default {
}
},
methods: {
initialValue() {
selectedOptions(value) {
if (this.multiple) {
return this.value ? this.options.filter(el => this.value.split(',').includes(el.value)) : []
return value ? this.options.filter(el => value.split(',').includes(el.value)) : []
} else {
return this.value ? this.options.find(el => el.value === this.value) : []
return value ? this.options.find(el => el.value === value) : []
}
},
onInput(val, id) {
Expand All @@ -72,7 +73,7 @@ export default {
},
watch: {
value (newValue, oldValue) {
this.currentValue = this.initialValue()
this.currentValue = this.selectedOptions(this.value)
}
},
mounted () {
Expand Down
4 changes: 4 additions & 0 deletions resources/lang/de/t.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php
return array(
"errors" => array(
"form_data_restored_please_submit_again" => "Deine eingegebenen Daten wurden wiederhergestellt. Speichern nicht vergessen!",
"session_expired_try_again" => "Ups, du bist inzwischen nicht mehr eingeloggt. Bitte logge dich nochmals ein, deine Eingaben werden dann wiederhergestellt.",
),
"footer" => array(
"slogan" => "Qualix. was gaffsch?",
),
Expand Down
4 changes: 4 additions & 0 deletions resources/lang/fr/t.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<?php
return array(
"errors" => array(
"form_data_restored_please_submit_again" => "Tes données saisies ont étés restaurées. N'oublie pas a sauvegarder!",
"session_expired_try_again" => "Oups, tu n'es plus inscrit. Merci de t'inscrire encore une fois, tes données saisies seront restaurées.",
),
"footer" => array(
"slogan" => "Qualix. quoi reluques-tu?",
),
Expand Down
4 changes: 2 additions & 2 deletions resources/views/auth/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class="btn btn-hitobito form-control{{ $errors->has('hitobito') ? ' is-invalid'
<form method="POST" action="{{ route('login') }}">
@csrf

<div class="form-group row">
<div class="form-group row required">
<label for="email" class="col-md-3 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

<div class="col-md-6">
Expand All @@ -38,7 +38,7 @@ class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email
</div>
</div>

<div class="form-group row">
<div class="form-group row required">
<label for="password" class="col-md-3 col-form-label text-md-right">{{ __('Password') }}</label>

<div class="col-md-6">
Expand Down
2 changes: 1 addition & 1 deletion resources/views/auth/passwords/email.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<form method="POST" action="{{ route('password.email') }}">
@csrf

<div class="form-group row">
<div class="form-group row required">
<label for="email" class="col-md-3 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

<div class="col-md-6">
Expand Down
10 changes: 5 additions & 5 deletions resources/views/auth/register.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

@section('content')
@component('components.card', ['header' => __('Register')])
<div class="form-group row">
<div class="form-group row required">
<div class="col-md-6 offset-md-3">
<a
class="btn btn-hitobito form-control{{ $errors->has('hitobito') ? ' is-invalid' : '' }}"
Expand All @@ -21,7 +21,7 @@ class="btn btn-hitobito form-control{{ $errors->has('hitobito') ? ' is-invalid'
<form method="POST" action="{{ route('register') }}">
@csrf

<div class="form-group row">
<div class="form-group row required">
<label for="name" class="col-md-3 col-form-label text-md-right">{{ __('Name') }}</label>

<div class="col-md-6">
Expand All @@ -36,7 +36,7 @@ class="btn btn-hitobito form-control{{ $errors->has('hitobito') ? ' is-invalid'
</div>
</div>

<div class="form-group row">
<div class="form-group row required">
<label for="email" class="col-md-3 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

<div class="col-md-6">
Expand All @@ -52,7 +52,7 @@ class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" name="email
</div>
</div>

<div class="form-group row">
<div class="form-group row required">
<label for="password" class="col-md-3 col-form-label text-md-right">{{ __('Password') }}</label>

<div class="col-md-6">
Expand All @@ -68,7 +68,7 @@ class="form-control{{ $errors->has('password') ? ' is-invalid' : '' }}" name="pa
</div>
</div>

<div class="form-group row">
<div class="form-group row required">
<label for="password-confirm"
class="col-md-3 col-form-label text-md-right">{{ __('Confirm Password') }}</label>

Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/form/checkboxInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
name="{{ $name }}"
class="custom-control-input{{ $errors->has($name) ? ' is-invalid' : '' }}"
value="1"
{{ ((isset($value) && $value) || (!isset($value) && old($name))) ? 'checked' : '' }}>
{{ (old($name) ?? $value ?? false) ? 'checked' : '' }}>
<label class="custom-control-label" for="{{ $name }}"></label>
</div>

Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/form/dateInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
id="{{ $name }}"
name="{{ $name }}"
class="form-control{{ $errors->has($name) ? ' is-invalid' : '' }}"
value="{{ isset($value) ? $value->format('d.m.Y') : old($name) }}"
value="{{ old($name) ?? $value->format('d.m.Y') ?? '' }}"
{{ isset($required) && $required ? 'required' : '' }}
{{ isset($autofocus) && $autofocus ? 'autofocus v-focus' : '' }}
:config="{ format: 'DD.MM.YYYY', useCurrent: false, locale: '{{App::getLocale()}}' }"></date-picker>
Expand Down
5 changes: 4 additions & 1 deletion resources/views/components/form/multiSelectInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
id="{{ $name }}"
name="{{ $name }}"
class="form-control-multiselect {{ $errors->has($name) ? ' is-invalid' : '' }}"
@if (old($name) !== null)
old-value="{{ old($name) }}"
@endif
@if (isset($valueBind) && $valueBind)
:value="{{ $valueBind }}"
@else
value="{{ isset($value) ? $value : old($name) }}"
value="{{ $value ?? '' }}"
@endif
{{ isset($required) && $required ? 'required' : '' }}
:allow-empty="true"
Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/form/radioButtonInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="my-auto">
@foreach($options as $optionValue => $option)
<div class="custom-control custom-radio horizontal-radio">
<input type="radio" id="{{ $name . $optionValue }}" name="{{ $name }}" value="{{ $optionValue }}" class="custom-control-input"{{ ((isset($value) && $value == $optionValue) || (!isset($value) && old($name) && old($name) == $optionValue)) ? ' checked' : '' }}>
<input type="radio" id="{{ $name . $optionValue }}" name="{{ $name }}" value="{{ $optionValue }}" class="custom-control-input"{{ ((old($name) ?? $value ?? null) == $optionValue) ? ' checked' : '' }}>
<label class="custom-control-label" for="{{ $name . $optionValue }}">{{ $option }}</label>
</div>
@endforeach
Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/form/textInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
id="{{ $name }}"
name="{{ $name }}"
class="form-control{{ $errors->has($name) ? ' is-invalid' : '' }}"
value="{{ isset($value) ? $value : old($name) }}"
value="{{ old($name) ?? $value ?? '' }}"
{{ isset($required) && $required ? 'required' : '' }}
{{ isset($autofocus) && $autofocus ? 'autofocus v-focus' : '' }}>

Expand Down
2 changes: 1 addition & 1 deletion resources/views/components/form/textareaInput.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
name="{{ $name }}"
class="form-control{{ $errors->has($name) ? ' is-invalid' : '' }}"
{{ isset($required) && $required ? 'required' : '' }}
{{ isset($autofocus) && $autofocus ? 'autofocus v-focus' : '' }}>{{ isset($value) ? $value : old($name) }}</textarea>
{{ isset($autofocus) && $autofocus ? 'autofocus v-focus' : '' }}>{{ old($name) ?? $value ?? '' }}</textarea>

@if ($errors->has($name))
<span class="invalid-feedback" role="alert">
Expand Down
6 changes: 3 additions & 3 deletions resources/views/observation/new.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
'name' => 'participant_ids',
'label' => __('t.models.observation.participant'),
'required' => true,
'value' => $participant_id ?? '',
'value' => $participant_id,
'options' => $course->participants->all(),
'valueFn' => function(\App\Models\Participant $participant) { return $participant->id; },
'displayFn' => function(\App\Models\Participant $participant) { return $participant->scout_name; },
Expand All @@ -20,13 +20,13 @@

@component('components.form.textareaInput', ['name' => 'content', 'label' => __('t.models.observation.content'), 'required' => true, 'autofocus' => ($participant_id !== null)])@endcomponent

<block-and-requirements-input-wrapper v-slot="slotProps">
<block-and-requirements-input-wrapper v-slot="slotProps" @if(old('requirement_ids', 'OBSERVATION_NO_OLD_VALUES') !== 'OBSERVATION_NO_OLD_VALUES') :has-old-values="true" @endif>

@component('components.form.multiSelectInput', [
'name' => 'block_id',
'label' => __('t.models.observation.block'),
'required' => true,
'value' => $block_id ?? '',
'value' => $block_id,
'options' => $course->blocks->all(),
'valueFn' => function(\App\Models\Block $block) { return $block->id; },
'displayFn' => function(\App\Models\Block $block) { return $block->blockname_and_number; },
Expand Down
2 changes: 1 addition & 1 deletion routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::middleware(['auth', 'verified'])->group(function () {
Route::middleware(['auth', 'verified', 'restoreFormData'])->group(function () {

Route::get('/', 'CourseController@noCourse')->name('home');
Route::get('/course', 'CourseController@noCourse');
Expand Down
Loading

0 comments on commit a92da94

Please sign in to comment.