Implement poll voting

This commit is contained in:
Les De Ridder 2018-10-17 15:12:20 +02:00
parent 562c45713d
commit a2d2d6e557
6 changed files with 118 additions and 20 deletions

View File

@ -6,7 +6,10 @@ use Illuminate\Http\Request;
use Carbon\Carbon; use Carbon\Carbon;
use Validator; use Validator;
use DB;
use App\Poll; use App\Poll;
use App\PollVote;
use App\PollVotingCode;
class PollController extends Controller class PollController extends Controller
{ {
@ -77,12 +80,87 @@ class PollController extends Controller
//TODO: Implement JSON output //TODO: Implement JSON output
return null; return null;
} else { } else {
return view('view_poll')->with('poll', $poll)->with('new', $new); return view('view_poll')
->with('poll', $poll)
->with('new', $new)
->with('hasVoted', $this->hasVoted($request, $poll));
} }
} }
public function viewResults(Request $request, Poll $poll)
{
if($poll->results_visible) {
} else {
}
}
private static function createPieChart(Poll $poll)
{
//TODO
}
public function hasVoted(Request $request, Poll $poll)
{
if($poll->duplicate_vote_checking == 'cookies') {
if($request->session()->exists($poll->id)) {
return true;
}
} else if($poll->duplicate_vote_checking == 'codes') {
$code = PollVotingCode::find($request->query('code'));
if($code == null || $code->used) {
return true;
}
}
return false;
}
public function vote(Request $request, Poll $poll) public function vote(Request $request, Poll $poll)
{ {
if($this->hasVoted($request, $poll)) {
return null;
}
if($poll->allow_multiple_answers) {
$validatedInput = $request->validate([
'options' => 'required|distinct',
]);
} else {
$validatedInput = $request->validate([
'options' => 'required|distinct|min:1|max:1',
]);
}
DB::beginTransaction();
foreach($validatedInput['options'] as $option)
{
//TODO: Properly display errors
if($poll->options()->find($option) == null) {
DB::rollBack();
return null;
}
$vote = new PollVote;
$vote->poll_option_id = $option;
$poll->votes()->save($vote);
}
DB::commit();
if($poll->duplicate_vote_checking == 'cookies') {
$request->session()->put($poll->id, null);
} else if($poll->duplicate_vote_checking == 'codes') {
$code->used = true;
$code->save();
}
//return redirect('PollController@viewResults', ['poll' => $poll]);
return view('view_poll')->with('poll', $poll)->with('new', false);
} }
public function admin(Request $request, Poll $poll) public function admin(Request $request, Poll $poll)

View File

@ -42,7 +42,6 @@ class Poll extends Model
public function voting_codes() public function voting_codes()
{ {
return $this->hasMany('App\PollVotingCode'); return $this->hasMany('App\PollVotingCode');
} }
public function createVotingCodes($n) public function createVotingCodes($n)
@ -56,4 +55,9 @@ class Poll extends Model
return $codes; return $codes;
} }
public function getResultsVisibleAttribute()
{
return !$this->hide_results_until_closed || ($this->closes_at != null && $this->closes_at->isPast());
}
} }

View File

@ -6,6 +6,8 @@ use Illuminate\Database\Eloquent\Model;
class PollVote extends Model class PollVote extends Model
{ {
protected $primaryKey = null;
public $incrementing = false;
public $timestamps = false; public $timestamps = false;
public function poll() public function poll()

View File

@ -167,6 +167,7 @@ return [
App\Providers\RouteServiceProvider::class, App\Providers\RouteServiceProvider::class,
Stolz\HtmlTidy\ServiceProvider::class, Stolz\HtmlTidy\ServiceProvider::class,
], ],
/* /*

View File

@ -7,25 +7,34 @@ $type = $poll->allow_multiple_answers ? "checkbox" : "radio";
@endphp @endphp
@section('content') @section('content')
<form> @if($hasVoted)
<section class="grid grid--large"> <section>
<div> <span>You have already voted on this poll.</span>
@foreach ($poll->options as $option)
<label class="{{$type}} no-bottom-margin">
<input type="{{$type}}" name="option" value="{{$option->id}}">
<span class="{{$type}}__label">{{$option->text}}</span>
</label>
<br> <br>
@endforeach
</div>
<div>
<!-- TODO: Pie chart (http://lavacharts.com/#example-pie) -->
</div>
</section>
<section class="some-top-margin"> @if($poll->results_visible)
<input type="submit" class="btn" value="Submit vote"> <div class="some-top-margin">
<span><a href="{{ action('PollController@viewResults', ['poll' => $poll]) }}">Results</a></span>
</div>
@endif
</section> </section>
</form> @else
<form action"={{ action('PollController@vote', ['poll' => $poll]) }}" method="post">
@csrf
@foreach ($poll->options as $option)
<label class="{{$type}} no-bottom-margin">
<input type="{{$type}}" name="options[]" value="{{$option->id}}">
<span class="{{$type}}__label">{{$option->text}}</span>
</label>
<br>
@endforeach
<section class="some-top-margin">
<input type="submit" class="btn" value="Submit vote">
</section>
</form>
@endif
@endsection @endsection

View File

@ -19,8 +19,12 @@ Route::get('/poll', 'PollController');
Route::post('/poll', 'PollController@create'); Route::post('/poll', 'PollController@create');
Route::get('/poll/{poll}', 'PollController@view'); Route::get('/poll/{poll}', 'PollController@view');
//TODO: Add admin GET route
Route::patch('/poll/{poll}', 'PollController@edit'); Route::patch('/poll/{poll}', 'PollController@edit');
Route::get('/poll/{poll}/results', 'PollController@viewResults');
Route::post('/poll/{poll}/vote', 'PollController@vote'); Route::post('/poll/{poll}/vote', 'PollController@vote');
Route::get('/poll/{poll}/edit', 'PollController@admin'); Route::get('/poll/{poll}/edit', 'PollController@admin');