Files
E-Vote/app/Http/Controllers/API/v1/Election/VoteController.php
T

174 lines
5.4 KiB
PHP

<?php
namespace App\Http\Controllers\API\v1\Election;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Util;
use App\Position;
use App\Nominee;
use App\Result;
class VoteController extends Controller
{
public function __invoke(Request $request)
{
$validation = $this->validateRequest($request);
if (($validation['status'] ?? 'failed') === 'failed') {
return response()->json($validation);
}
$this->insertVote($request);
$user = Auth::guard('voter')->user() ?: $request->user();
$vote = is_array($request->vote) ? $request->vote : [];
$positionsVoted = 0;
$totalSelections = 0;
foreach ($vote as $value) {
$nomineeIds = $value['nominee_id'] ?? null;
if (is_array($nomineeIds) && count($nomineeIds)) {
$positionsVoted++;
$totalSelections += count($nomineeIds);
}
}
activity()
->performedOn($user)
->withProperties([
'election_id' => Util::getCurrentElection(),
'voter_id' => Auth::id(),
'voter_name' => $user ? $user->name : null,
'positions_voted' => $positionsVoted,
'total_selections' => $totalSelections,
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
])
->log('submit vote');
return response()->json([
'status' => 'success',
'message' => 'Undian anda telah berjaya dihantar.',
'result' => Result::where('voter_id', Auth::id())->get()
]);
}
private function insertVote($request)
{
$vote = $request->vote;
if (!is_array($vote)) return;
foreach ($vote as $value) {
$positionId = $value['position_id'] ?? null;
$nomineeIds = $value['nominee_id'] ?? [];
if (!$positionId || !is_array($nomineeIds) || !count($nomineeIds)) continue;
foreach ($nomineeIds as $nomineeId) {
Result::updateOrCreate([
'voter_id' => Auth::id(),
'election_id' => Util::getCurrentElection(),
'position_id' => $positionId,
'nominee_id' => $nomineeId,
]);
}
}
}
private function validNominee($id, $position_id)
{
try{
$nominee = Nominee::where('position_id', '=', $position_id)->whereIn('id',$id)->count();
}catch(\Exception $e){
return 0;
}
return $nominee;
}
private function isPositionExist($id)
{
try{
return Position::where('id', $id)->count();
}catch(\Exception $e){
return 0;
}
}
private function voteAllPosition($request)
{
$total_position = Position::where('election_id', Util::getCurrentElection())->count();
$total_vote = !empty($request->vote) ? count($request->vote) : 0;
return $total_vote >= $total_position;
}
private function validateRequest($request)
{
$result['status'] = 'failed';
$vote = $request->vote;
if (!is_array($vote) || !count($vote)) {
$result['message'] = 'You must vote on at least one position.';
return $result;
}
foreach ($vote as $value) {
/**
* Check if position_id and nominee_id has a value
*/
// dd($vote,$value);
$positionId = $value['position_id'] ?? null;
$nomineeIds = $value['nominee_id'] ?? null;
if (empty($positionId)) {
$result['message'] = 'Invalid Position.';
return $result;
}
if (!is_array($nomineeIds) || !count($nomineeIds)) {
// Skip empty positions; allow partial voting setups (UI may send all positions with empty arrays)
continue;
}
if (count($nomineeIds) > 1) {
$result['message'] = 'You can only vote for one nominee.';
return $result;
}
/**
* Check if the Position you vote exists
*/
if (!$this->isPositionExist($positionId)) {
$result['message'] = 'Invalid Position.';
return $result;
}
/**
* Check if the Nominee you vote on certain position exists
*/
// elseif (!$this->validNominee($value['nominee_id'], $value['position_id'])) {
elseif($this->validNominee($nomineeIds, $positionId) <= 0){
$result['message'] = 'Invalid Nominee for '.Position::find($positionId)->name.' position.';
return $result;
}
}
// Ensure at least one actual vote exists
$hasAny = false;
foreach ($vote as $value) {
$nomineeIds = $value['nominee_id'] ?? null;
if (is_array($nomineeIds) && count($nomineeIds)) {
$hasAny = true;
break;
}
}
if (!$hasAny) {
$result['message'] = 'You must vote on at least one position.';
return $result;
}
return ['status' => 'success'];
}
}