Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
FaqController
100.00% covered (success)
100.00%
46 / 46
100.00% covered (success)
100.00%
5 / 5
9
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
 edit
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 save
100.00% covered (success)
100.00%
34 / 34
100.00% covered (success)
100.00%
1 / 1
5
 delete
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 showEdit
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Controllers\Admin;
6
7use Engelsystem\Controllers\BaseController;
8use Engelsystem\Controllers\HasUserNotifications;
9use Engelsystem\Http\Redirector;
10use Engelsystem\Http\Request;
11use Engelsystem\Http\Response;
12use Engelsystem\Models\Faq;
13use Engelsystem\Models\Tag;
14use Illuminate\Support\Collection;
15use Psr\Log\LoggerInterface;
16
17class FaqController extends BaseController
18{
19    use HasUserNotifications;
20
21    /** @var array<string> */
22    protected array $permissions = [
23        'faq.view',
24        'faq.edit',
25    ];
26
27    public function __construct(
28        protected LoggerInterface $log,
29        protected Faq $faq,
30        protected Redirector $redirect,
31        protected Response $response
32    ) {
33    }
34
35    public function edit(Request $request): Response
36    {
37        $faqId = $request->getAttribute('faq_id'); // optional
38
39        $faq = $this->faq->with('tags')->find($faqId);
40
41        return $this->showEdit($faq);
42    }
43
44    public function save(Request $request): Response
45    {
46        $faqId = $request->getAttribute('faq_id'); // optional
47
48        /** @var Faq $faq */
49        $faq = $this->faq->findOrNew($faqId);
50
51        if ($request->request->has('delete')) {
52            return $this->delete($faq);
53        }
54
55        $data = $this->validate($request, [
56            'question' => 'required|max:255',
57            'text'     => 'required',
58            'tags'     => 'optional',
59            'delete'   => 'optional|checked',
60            'preview'  => 'optional|checked',
61        ]);
62
63        $faq->question = $data['question'];
64        $faq->text = $data['text'];
65
66        $tags = collect(explode(',', $data['tags'] ?? ''))
67            ->transform(fn($value) => trim($value))
68            ->filter(fn($value) => $value != '')
69            ->unique();
70
71        if (!is_null($data['preview'])) {
72            $faq['tags'] = new Collection();
73            foreach ($tags as $tagName) {
74                $tag = new Tag(['name' => $tagName]);
75                $faq['tags'][] = $tag;
76            }
77
78            return $this->showEdit($faq, $data['tags']);
79        }
80
81        $faq->save();
82
83        $faq->tags()->detach();
84        foreach ($tags as $tagName) {
85            $tag = Tag::whereName($tagName)->firstOrCreate(['name' => $tagName]);
86            $faq->tags()->attach($tag);
87        }
88
89        $this->log->info(
90            'Saved faq "{question}" ({id}): {text}',
91            ['question' => $faq->question, 'text' => $faq->text, 'id' => $faq->id]
92        );
93
94        $this->addNotification('faq.edit.success');
95
96        return $this->redirect->to('/faq#faq-' . $faq->id);
97    }
98
99    protected function delete(Faq $faq): Response
100    {
101        $faq->delete();
102
103        $this->log->info('Deleted faq "{question}" ({id})', ['question' => $faq->question, 'id' => $faq->id]);
104
105        $this->addNotification('faq.delete.success');
106
107        return $this->redirect->to('/faq');
108    }
109
110    protected function showEdit(?Faq $faq, ?string $tags = null): Response
111    {
112        return $this->response->withView(
113            'pages/faq/edit.twig',
114            ['faq' => $faq, 'tags' => $tags]
115        );
116    }
117}