Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
80 / 80
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
UserWorklogController
100.00% covered (success)
100.00%
80 / 80
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%
30 / 30
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%
18 / 18
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            '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}