Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
80 / 80 |
|
100.00% |
7 / 7 |
CRAP | |
100.00% |
1 / 1 |
UserWorklogController | |
100.00% |
80 / 80 |
|
100.00% |
7 / 7 |
16 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
editWorklog | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
saveWorklog | |
100.00% |
30 / 30 |
|
100.00% |
1 / 1 |
4 | |||
showDeleteWorklog | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
deleteWorklog | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
2 | |||
showEditWorklog | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
1 | |||
needsUser | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Engelsystem\Controllers\Admin; |
6 | |
7 | use Carbon\Carbon; |
8 | use Engelsystem\Config\Config; |
9 | use Engelsystem\Controllers\BaseController; |
10 | use Engelsystem\Controllers\HasUserNotifications; |
11 | use Engelsystem\Helpers\Authenticator; |
12 | use Engelsystem\Http\Exceptions\HttpForbidden; |
13 | use Engelsystem\Http\Exceptions\HttpNotFound; |
14 | use Engelsystem\Http\Redirector; |
15 | use Engelsystem\Http\Request; |
16 | use Engelsystem\Http\Response; |
17 | use Engelsystem\Models\User\User; |
18 | use Engelsystem\Models\Worklog; |
19 | use Psr\Log\LoggerInterface; |
20 | |
21 | class 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 | 'Added worklog for {name} ({id}) at {time} spanning {hours}h: {text}', |
88 | [ |
89 | 'name' => $user->name, |
90 | 'id' => $user->id, |
91 | 'time' => $worklog->worked_at, |
92 | 'hours' => $worklog->hours, |
93 | 'text' => $worklog->comment, |
94 | ] |
95 | ); |
96 | $this->addNotification(isset($worklogId) ? 'worklog.edit.success' : 'worklog.add.success'); |
97 | |
98 | return $this->redirect->to('/users?action=view&user_id=' . $user->id); |
99 | // TODO Once User_view.php gets removed, change this to withView + getNotifications |
100 | } |
101 | |
102 | public function showDeleteWorklog(Request $request): Response |
103 | { |
104 | $user = $this->needsUser($request); |
105 | $worklogId = $request->getAttribute('worklog_id'); |
106 | $worklog = $this->worklog->findOrFail($worklogId); |
107 | |
108 | if ($worklog->user->id != $user->id) { |
109 | throw new HttpNotFound(); |
110 | } |
111 | |
112 | return $this->response->withView( |
113 | 'admin/user/delete-worklog.twig', |
114 | ['userdata' => $user] |
115 | ); |
116 | } |
117 | |
118 | public function deleteWorklog(Request $request): Response |
119 | { |
120 | $user = $this->needsUser($request); |
121 | $worklogId = $request->getAttribute('worklog_id'); |
122 | $worklog = $this->worklog->findOrFail($worklogId); |
123 | |
124 | if ($worklog->user->id != $user->id) { |
125 | throw new HttpNotFound(); |
126 | } |
127 | $worklog->delete(); |
128 | |
129 | $this->log->info( |
130 | 'Deleted worklog for {name} ({id}) at {time} spanning {hours}h: {text}', |
131 | [ |
132 | 'name' => $worklog->user->name, |
133 | 'id' => $worklog->user->id, |
134 | 'time' => $worklog->worked_at, |
135 | 'hours' => $worklog->hours, |
136 | 'text' => $worklog->comment, |
137 | ] |
138 | ); |
139 | $this->addNotification('worklog.delete.success'); |
140 | |
141 | return $this->redirect->to('/users?action=view&user_id=' . $user->id); |
142 | // TODO Once User_view.php gets removed, change this to withView + getNotifications |
143 | } |
144 | |
145 | private function showEditWorklog( |
146 | User $user, |
147 | Carbon $work_date, |
148 | float $work_hours = 0, |
149 | string $comment = '', |
150 | bool $is_edit = false |
151 | ): Response { |
152 | return $this->response->withView( |
153 | 'admin/user/edit-worklog.twig', |
154 | [ |
155 | 'userdata' => $user, |
156 | 'work_date' => $work_date, |
157 | 'work_hours' => $work_hours, |
158 | 'comment' => $comment, |
159 | 'is_edit' => $is_edit, |
160 | ] |
161 | ); |
162 | } |
163 | |
164 | private function needsUser(Request $request): User |
165 | { |
166 | $userId = (int) $request->getAttribute('user_id'); |
167 | if (!config('enable_self_worklog') && ($userId === $this->auth->user()->id)) { |
168 | throw new HttpForbidden(); |
169 | } |
170 | return $this->user->findOrFail($userId); |
171 | } |
172 | } |