Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
50 / 50
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
UserGoodieController
100.00% covered (success)
100.00%
50 / 50
100.00% covered (success)
100.00%
4 / 4
14
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
 checkActive
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 editGoodie
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 saveGoodie
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Controllers\Admin;
6
7use Carbon\Carbon;
8use Engelsystem\Config\Config;
9use Engelsystem\Config\GoodieType;
10use Engelsystem\Controllers\BaseController;
11use Engelsystem\Controllers\HasUserNotifications;
12use Engelsystem\Helpers\Authenticator;
13use Engelsystem\Helpers\Goodie;
14use Engelsystem\Http\Exceptions\HttpNotFound;
15use Engelsystem\Http\Redirector;
16use Engelsystem\Http\Request;
17use Engelsystem\Http\Response;
18use Engelsystem\Models\User\User;
19use Psr\Log\LoggerInterface;
20
21class UserGoodieController extends BaseController
22{
23    use HasUserNotifications;
24
25    /** @var array<string, string> */
26    protected array $permissions = [
27        'editGoodie' => 'user.goodie.edit',
28        'saveGoodie' => 'user.goodie.edit',
29    ];
30
31    public function __construct(
32        protected Authenticator $auth,
33        protected Config $config,
34        protected LoggerInterface $log,
35        protected Redirector $redirect,
36        protected Response $response,
37        protected User $user
38    ) {
39    }
40
41    private function checkActive(): void
42    {
43        if (GoodieType::from(config('goodie_type')) == GoodieType::None) {
44            throw new HttpNotFound();
45        }
46    }
47
48    public function editGoodie(Request $request): Response
49    {
50        $this->checkActive();
51        $userId = (int) $request->getAttribute('user_id');
52
53        /** @var User $user */
54        $user = $this->user->findOrFail($userId);
55        $goodieScore = $user->state->force_active ? '~' : Goodie::userScore($user);
56
57        return $this->response->withView(
58            'admin/user/edit-goodie.twig',
59            [
60                'userdata' => $user,
61                'is_tshirt' => $this->config->get('goodie_type') === GoodieType::Tshirt->value,
62                'goodie_score' => $goodieScore,
63            ]
64        );
65    }
66
67    public function saveGoodie(Request $request): Response
68    {
69        $this->checkActive();
70        $userId = (int) $request->getAttribute('user_id');
71        $shirtEnabled = $this->config->get('goodie_type') === GoodieType::Tshirt->value;
72        /** @var User $user */
73        $user = $this->user->findOrFail($userId);
74
75        $data = $this->validate($request, [
76            'shirt_size' => ($shirtEnabled ? 'required' : 'optional') . '|shirt_size',
77            'arrived'    => 'optional|checked',
78            'active'     => 'optional|checked',
79            'got_goodie' => 'optional|checked',
80        ]);
81
82        if ($shirtEnabled) {
83            $user->personalData->shirt_size = $data['shirt_size'];
84            $user->personalData->save();
85        }
86
87        if ($this->auth->can('admin_arrive')) {
88            if ($user->state->arrived != (bool) $data['arrived']) {
89                if ((bool) $data['arrived']) {
90                    $user->state->arrival_date = new Carbon();
91                } else {
92                    $user->state->arrival_date = null;
93                }
94            }
95        }
96
97        $user->state->active = (bool) $data['active'];
98        $user->state->got_goodie = (bool) $data['got_goodie'];
99        $user->state->save();
100
101        $this->log->info(
102            'Updated user goodie state {user} ({id}): '
103            . '{size}, arrived: {arrived}, active: {active}, got goodie: {got_goodie}',
104            [
105                'id'        => $user->id,
106                'user'      => $user->name,
107                'size'      => $user->personalData->shirt_size,
108                'arrived'   => $user->state->arrived ? 'yes' : 'no',
109                'active'    => $user->state->active ? 'yes' : 'no',
110                'got_goodie' => $user->state->got_goodie ? 'yes' : 'no',
111            ]
112        );
113
114        $this->addNotification('user.edit.success');
115
116        return $this->redirect->back();
117    }
118}