Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Http/Controllers/AbstractController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Requests\VoiceRequest;
use App\User;
use Auth;
use Illuminate\Routing\Controller as BaseController;

abstract class AbstractController extends BaseController
{
protected User $user;

public function __construct(VoiceRequest $request)
{
$request->replace($request->validated());
$this->user = Auth::user();
}
}
21 changes: 21 additions & 0 deletions Http/Controllers/VoiceController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Requests\VoiceRequest as Request;
use App\Models\Voice;

class VoiceController extends AbstractController
{
public function __construct(Request $request, private \App\Services\VoiceService $voiceService)
{
parent::__construct($request);
}

public function store(Request $request): Voice
{
return $this->voiceService->createVoice($this->user);
}
}
18 changes: 18 additions & 0 deletions Http/Requests/VoiceRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class VoiceRequest extends FormRequest
{
public function rules(): array
{
return [
'question_id' => 'required|int|exists:questions,id',
'value' => 'required|boolean',
];
}
}
15 changes: 15 additions & 0 deletions Repository/QuestionRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace App\Repository;

use App\Models\Question;

class QuestionRepository
{
public function getById(?int $id): Question
{
return Question::findOrFail($id);
}
}
19 changes: 19 additions & 0 deletions Repository/VoteRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace App\Repository;

use App\Models\Voice;

class VoteRepository
{
public function getUserVote(int $userId, int $questionId): ?Voice
{
return Voice::where([
['user_id', '=', $userId],
['question_id', '=', $questionId]
])
->first();
}
}
45 changes: 45 additions & 0 deletions Services/VoiceService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace App\Services;

use App\Http\Requests\VoiceRequest;
use App\Repository\QuestionRepository;
use App\Repository\VoteRepository;
use App\Models\Voice;
use App\Models\User;
use Auth;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class VoiceService
{
public function __construct(private VoiceRequest $request, private QuestionRepository $questionRepository, private VoteRepository $voteRepository)
{
}

public function createVoice(User $user): Voice
{
$question = $this->questionRepository->getById($this->request->post('question_id'));

//@todo move to a middleware
if ($question->user_id == $user->id) {
throw new AccessDeniedHttpException('The user is not allowed to vote to your question');
}

$userVote = $this->voteRepository->getUserVote($user->id, $question->id);

//@todo move to a middleware
if (null !== $userVote && $userVote->value === $this->request->post('value')) {
throw new AccessDeniedHttpException('The user is not allowed to vote more than once');
}

return $question->voice()->updateOrCreate(
['id' => $userVote ? $userVote->id : -1],
[
'user_id' => $user->id,
'value' => $this->request->post('value')
]
);
}
}