Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
82 / 82
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
UserWorklogController
100.00% covered (success)
100.00%
82 / 82
100.00% covered (success)
100.00%
7 / 7
16
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
 editWorklog
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 saveWorklog
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
4
 showDeleteWorklog
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 deleteWorklog
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
2
 showEditWorklog
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 needsUser
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace Engelsystem\Controllers\Admin;
6
7use Carbon\Carbon;
8use Engelsystem\Config\Config;
9use Engelsystem\Controllers\BaseController;
10use Engelsystem\Controllers\HasUserNotifications;
11use Engelsystem\Helpers\Authenticator;
12use Engelsystem\Http\Exceptions\HttpForbidden;
13use Engelsystem\Http\Exceptions\HttpNotFound;
14use Engelsystem\Http\Redirector;
15use Engelsystem\Http\Request;
16use Engelsystem\Http\Response;
17use Engelsystem\Models\User\User;
18use Engelsystem\Models\Worklog;
19use Psr\Log\LoggerInterface;
20
21class UserWorklogController extends BaseController
22{
23    use HasUserNotifications;
24
25    /** @var array<string> */
26    protected array $permissions = [
27        'admin_user_worklog',
28    ];
29
30    public function __construct(
31        protected Authenticator $auth,
32        protected Config $config,
33        protected LoggerInterface $log,
34        protected Worklog $worklog,
35        protected Redirector $redirect,
36        protected Response $response,
37        protected User $user
38    ) {
39    }
40
41    public function editWorklog(Request $request): Response
42    {
43        $user = $this->needsUser($request);
44        $worklogId = $request->getAttribute('worklog_id'); // optional
45
46        if (isset($worklogId)) {
47            $worklog = $this->worklog->findOrFail((int) $worklogId);
48
49            if ($worklog->user->id != $user->id) {
50                throw new HttpNotFound();
51            }
52            return $this->showEditWorklog($user, $worklog->worked_at, $worklog->hours, $worklog->comment, true);
53        } else {
54            return $this->showEditWorklog($user, Carbon::today());
55        }
56    }
57
58    public function saveWorklog(Request $request): Response
59    {
60        $user = $this->needsUser($request);
61        $worklogId = $request->getAttribute('worklog_id'); // optional
62
63        $data = $this->validate($request, [
64            'work_date' => 'required|date:Y-m-d',
65            'work_hours' => 'float|min:0',
66            'comment' => 'required|max:200',
67        ]);
68
69        // Search / create worklog
70        if (isset($worklogId)) {
71            $worklog = $this->worklog->findOrFail((int) $worklogId);
72
73            if ($worklog->user->id != $user->id) {
74                throw new HttpNotFound();
75            }
76        } else {
77            $worklog = new Worklog();
78            $worklog->user()->associate($user);
79            $worklog->creator()->associate($this->auth->user());
80        }
81        $worklog->worked_at = $data['work_date'];
82        $worklog->hours = $data['work_hours'];
83        $worklog->comment = $data['comment'];
84        $worklog->save();
85
86        $this->log->info(
87            'Saved worklog ({wl_id}) for {name} ({id}) at {time} spanning {hours}h: {text}',
88            [
89                'wl_id' => $worklog->id,
90                'name' => $user->name,
91                'id' => $user->id,
92                'time' => $worklog->worked_at,
93                'hours' => $worklog->hours,
94                'text' => $worklog->comment,
95            ]
96        );
97        $this->addNotification(isset($worklogId) ? 'worklog.edit.success' : 'worklog.add.success');
98
99        return $this->redirect->to('/users?action=view&user_id=' . $user->id);
100        // TODO Once User_view.php gets removed, change this to withView + getNotifications
101    }
102
103    public function showDeleteWorklog(Request $request): Response
104    {
105        $user = $this->needsUser($request);
106        $worklogId = $request->getAttribute('worklog_id');
107        $worklog = $this->worklog->findOrFail($worklogId);
108
109        if ($worklog->user->id != $user->id) {
110            throw new HttpNotFound();
111        }
112
113        return $this->response->withView(
114            'admin/user/delete-worklog.twig',
115            ['userdata' => $user]
116        );
117    }
118
119    public function deleteWorklog(Request $request): Response
120    {
121        $user = $this->needsUser($request);
122        $worklogId = $request->getAttribute('worklog_id');
123        $worklog = $this->worklog->findOrFail($worklogId);
124
125        if ($worklog->user->id != $user->id) {
126            throw new HttpNotFound();
127        }
128        $worklog->delete();
129
130        $this->log->info(
131            'Deleted worklog ({wl_id}) for {name} ({id}) at {time} spanning {hours}h: {text}',
132            [
133                'wl_id' => $worklog->id,
134                'name' => $worklog->user->name,
135                'id' => $worklog->user->id,
136                'time' => $worklog->worked_at,
137                'hours' => $worklog->hours,
138                'text' => $worklog->comment,
139            ]
140        );
141        $this->addNotification('worklog.delete.success');
142
143        return $this->redirect->to('/users?action=view&user_id=' . $user->id);
144        // TODO Once User_view.php gets removed, change this to withView + getNotifications
145    }
146
147    private function showEditWorklog(
148        User $user,
149        Carbon $work_date,
150        float $work_hours = 0,
151        string $comment = '',
152        bool $is_edit = false
153    ): Response {
154        return $this->response->withView(
155            'admin/user/edit-worklog.twig',
156            [
157                'userdata' => $user,
158                'work_date' => $work_date,
159                'work_hours' => $work_hours,
160                'comment' => $comment,
161                'is_edit' => $is_edit,
162            ]
163        );
164    }
165
166    private function needsUser(Request $request): User
167    {
168        $userId = (int) $request->getAttribute('user_id');
169        if (!config('enable_self_worklog') && ($userId === $this->auth->user()->id)) {
170            throw new HttpForbidden();
171        }
172        return $this->user->findOrFail($userId);
173    }
174}