Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
QuestionsController
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
5 / 5
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 index
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 add
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 delete
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
2
 save
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Controllers;
6
7use Engelsystem\Helpers\Authenticator;
8use Engelsystem\Http\Exceptions\HttpForbidden;
9use Engelsystem\Http\Redirector;
10use Engelsystem\Http\Request;
11use Engelsystem\Http\Response;
12use Engelsystem\Models\Question;
13use Psr\Log\LoggerInterface;
14
15class QuestionsController extends BaseController
16{
17    use HasUserNotifications;
18
19    /** @var string[] */
20    protected array $permissions = [
21        'question.add',
22    ];
23
24    public function __construct(
25        protected Authenticator $auth,
26        protected LoggerInterface $log,
27        protected Question $question,
28        protected Redirector $redirect,
29        protected Response $response
30    ) {
31    }
32
33    public function index(): Response
34    {
35        $questions = $this->question
36            ->whereUserId($this->auth->user()->id)
37            ->orderByDesc('answered_at')
38            ->orderBy('created_at')
39            ->get()
40            ->load(['user.state', 'answerer.state']);
41
42        return $this->response->withView(
43            'pages/questions/index.twig',
44            ['questions' => $questions]
45        );
46    }
47
48    public function add(): Response
49    {
50        return $this->response->withView(
51            'pages/questions/edit.twig',
52            ['question' => null]
53        );
54    }
55
56    public function delete(Request $request): Response
57    {
58        $data = $this->validate(
59            $request,
60            [
61                'id'     => 'required|int',
62                'delete' => 'checked',
63            ]
64        );
65
66        $question = $this->question->findOrFail($data['id']);
67        if ($question->user->id != $this->auth->user()->id) {
68            throw new HttpForbidden();
69        }
70
71        $question->delete();
72
73        $this->log->info('Deleted own question {question}', ['question' => $question->text]);
74        $this->addNotification('question.delete.success');
75
76        return $this->redirect->to('/questions');
77    }
78
79    public function save(Request $request): Response
80    {
81        $data = $this->validate(
82            $request,
83            [
84                'text' => 'required',
85            ]
86        );
87
88        $question = new Question();
89        $question->user()->associate($this->auth->user());
90        $question->text = $data['text'];
91        $question->save();
92
93        $this->log->info(
94            'Asked: {question}',
95            [
96                'question' => $question->text,
97            ]
98        );
99
100        $this->addNotification('question.add.success');
101
102        return $this->redirect->to('/questions');
103    }
104}