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