• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

klinge / sl-webapp / 18188466427

02 Oct 2025 09:03AM UTC coverage: 61.928% (-1.1%) from 63.01%
18188466427

push

github

web-flow
Merge pull request #105 from klinge/65-add-a-better-routerdispatcher

Changes to League Route instead of AltoRouter

65 of 98 new or added lines in 11 files covered. (66.33%)

1 existing line in 1 file now uncovered.

1272 of 2054 relevant lines covered (61.93%)

3.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

22.22
/App/Controllers/MedlemController.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\Controllers;
6

7
use Exception;
8
use App\Models\Medlem;
9
use App\Models\MedlemRepository;
10
use App\Models\Roll;
11
use App\Models\BetalningRepository;
12
use App\Utils\View;
13
use App\Utils\Session;
14
use App\Services\MailAliasService;
15
use App\Services\MedlemDataValidatorService;
16
use App\Application;
17
use App\Traits\ResponseFormatter;
18
use Psr\Http\Message\ServerRequestInterface;
19
use Psr\Http\Message\ResponseInterface;
20
use PDO;
21
use Monolog\Logger;
22

23
/**
24
 * MedlemController handles operations related to members (medlemmar).
25
 *
26
 * This controller manages CRUD operations for members, including listing,
27
 * editing, creating, and deleting member records. It also handles related
28
 * operations such as managing roles and payments for members.
29
 */
30
class MedlemController extends BaseController
31
{
32
    use ResponseFormatter;
33

34
    private View $view;
35
    private MailAliasService $mailAliasService;
36
    private MedlemRepository $medlemRepo;
37
    private BetalningRepository $betalningRepo;
38
    private MedlemDataValidatorService $validator;
39
    private PDO $conn;
40

41
    /**
42
     * Constructs a new MedlemController instance.
43
     *
44
     * @param Application $app The application instance
45
     * @param ServerRequestInterface $request The request object
46
     */
47
    public function __construct(
48
        Application $app,
49
        ServerRequestInterface $request,
50
        Logger $logger,
51
        PDO $conn,
52
        BetalningRepository $betalningRepository
53
    ) {
54
        parent::__construct($app, $request, $logger);
4✔
55
        $this->conn = $conn;
4✔
56
        $this->view = new View($this->app);
4✔
57
        $this->medlemRepo = new MedlemRepository($this->conn, $this->logger);
4✔
58
        $this->betalningRepo = $betalningRepository;
4✔
59
        $this->mailAliasService = new MailAliasService($this->logger, $this->app->getConfig(null));
4✔
60
        $this->validator = new MedlemDataValidatorService();
4✔
61
    }
62

63
    /**
64
     * Lists all members.
65
     *
66
     * Fetches all members from the repository and renders them in a view.
67
     */
68
    public function listAll(): ResponseInterface
69
    {
70
        $result = $this->medlemRepo->getAll();
1✔
71

72
        //Put everyting in the data variable that is used by the view
73
        $data = [
1✔
74
            "title" => "Medlemmar",
1✔
75
            "items" => $result,
1✔
76
            'newAction' => $this->createUrl('medlem-new')
1✔
77
        ];
1✔
78
        return $this->view->render('viewMedlem', $data);
1✔
79
    }
80

81
    public function listJson(): ResponseInterface
82
    {
83
        $result = $this->medlemRepo->getAll();
1✔
84
        return $this->jsonResponse($result);
1✔
85
    }
86

87
    /**
88
     * Edits a specific member.
89
     *
90
     * Fetches member data, roles, sailings, and payments for the specified member ID
91
     * and renders them in an edit view.
92
     *
93
     * @param ServerRequestInterface $request The request object
94
     * @param array $params The route parameters, must contain 'id'
95
     */
96
    public function edit(ServerRequestInterface $request, array $params): ResponseInterface
97
    {
98
        $id = (int) $params['id'];
×
99

100
        //Fetch member data
101
        try {
102
            $medlem = new Medlem($this->conn, $this->logger, $id);
×
103
            $roll = new Roll($this->conn, $this->logger);
×
104
            //Fetch roles and seglingar to use in the view
105
            $roller = $roll->getAll();
×
106
            $seglingar = $medlem->getSeglingar();
×
107
            //fetch betalningar for member
108
            $betalningar = $this->betalningRepo->getBetalningForMedlem($id);
×
109

110
            $data = [
×
111
                "title" => "Visa medlem",
×
112
                "items" => $medlem,
×
113
                "roles" => $roller,
×
114
                'seglingar' => $seglingar,
×
115
                'betalningar' => $betalningar,
×
116
                //Used in the view to set the proper action url for the form
NEW
117
                'formAction' => $this->createUrl('medlem-update', ['id' => $id]),
×
NEW
118
                'createBetalningAction' => $this->createUrl('betalning-medlem', ['id' => $id]),
×
NEW
119
                'listBetalningAction' => $this->createUrl('betalning-medlem', ['id' => $id]),
×
NEW
120
                'deleteAction' => $this->createUrl('medlem-delete')
×
UNCOV
121
            ];
×
122

123
            return $this->view->render('viewMedlemEdit', $data);
×
124
        } catch (Exception $e) {
×
125
            return $this->redirectWithError('medlem-list', 'Kunde inte hämta medlem!');
×
126
        }
127
    }
128

129
    /**
130
     * Saves changes to a member.
131
     *
132
     * Sanitizes input data, updates the member record, and redirects to the member list.
133
     *
134
     * @param ServerRequestInterface $request The request object
135
     * @param array $params The route parameters, must contain 'id'
136
     */
137
    public function update(ServerRequestInterface $request, array $params): ResponseInterface
138
    {
139
        $id = (int) $params['id'];
×
140
        $medlem = new Medlem($this->conn, $this->logger, $id);
×
141
        $postData = $this->request->getParsedBody();
×
142

143
        if ($this->validator->validateAndPrepare($medlem, $postData)) {
×
144
            try {
145
                $medlem->save();
×
146
                if ($this->validator->hasEmailChanged()) {
×
147
                    $this->updateEmailAliases();
×
148
                }
149
                return $this->redirectWithSuccess(
×
150
                    'medlem-list',
×
151
                    'Medlem ' . $medlem->fornamn . ' ' . $medlem->efternamn . ' uppdaterad!'
×
152
                );
×
153
            } catch (Exception $e) {
×
154
                return $this->redirectWithError('medlem-list', 'Kunde inte uppdatera medlem! Fel: ' . $e->getMessage());
×
155
            }
156
        } else {
157
            //Error messages are set in the MedlemDataValidatorService so just redirect
158
            if (isset($medlem->id)) {
×
159
                return $this->redirectWithError('medlem-edit', '');
×
160
            } else {
161
                return $this->redirectWithError('medlem-new', '');
×
162
            }
163
        }
164
    }
165

166
    /**
167
     * Prepares and displays the form for adding a new member.
168
     *
169
     * This method:
170
     * 1. Retrieves all available roles from the Roll model.
171
     * 2. Prepares data for the view
172
     * 3. Renders the 'viewMedlemNew' template with the prepared data.
173
     *
174
     * @return ResponseInterface
175
     */
176
    public function showNewForm(): ResponseInterface
177
    {
178
        $roll = new Roll($this->conn, $this->logger);
×
179
        $roller = $roll->getAll();
×
180
        //Just show the form to add a new member
181
        $data = [
×
182
            "title" => "Lägg till medlem",
×
183
            "roller" => $roller,
×
184
            //Used in the view to set the proper action url for the form
NEW
185
            'formAction' => $this->createUrl('medlem-create')
×
186
        ];
×
187
        return $this->view->render('viewMedlemNew', $data);
×
188
    }
189

190
    /**
191
     * Inserts a new member into the system.
192
     *
193
     * This method handles the creation of a new member based on submitted POST data.
194
     * It performs the following steps:
195
     * 1. Creates a new Medlem object.
196
     * 2. Prepares and sanitizes the submitted member data.
197
     * 3. Attempts to create the new member record in the database.
198
     * 4. Sets a flash message indicating the result of the operation.
199
     * 5. Redirects to the member list page.
200
     *
201
     * @return ResponseInterface
202
     * @throws Exception If there's an error during the member creation process
203
     */
204
    public function create(): ResponseInterface
205
    {
206
        $medlem = new Medlem($this->conn, $this->logger);
×
207
        $postData = $this->request->getParsedBody();
×
208

209
        if ($this->validator->validateAndPrepare($medlem, $postData)) {
×
210
            try {
211
                $medlem->create();
×
212
                $this->updateEmailAliases();
×
213

214
                return $this->redirectWithSuccess(
×
215
                    'medlem-list',
×
216
                    'Medlem ' . $medlem->fornamn . ' ' . $medlem->efternamn . ' skapad!'
×
217
                );
×
218
            } catch (Exception $e) {
×
219
                return $this->redirectWithError(
×
220
                    'medlem-create',
×
221
                    'Kunde inte skapa medlem! Fel: ' . $e->getMessage()
×
222
                );
×
223
            }
224
        } else {
225
            //Error messages are set in the MedlemDataValidatorService so just redirect
226
            if (isset($medlem->id)) {
×
227
                return $this->redirectWithError('medlem-edit', '');
×
228
            } else {
229
                return $this->redirectWithError('medlem-new', '');
×
230
            }
231
        }
232
    }
233

234
    /**
235
     * Deletes a member from the system.
236
     *
237
     * This method handles the deletion of a member based on the provided ID.
238
     * It attempts to delete the member and sets a flash message indicating
239
     * the result of the operation. After deletion, it redirects to the member list.
240
     *
241
     * @throws Exception If there's an error during the deletion process
242
     */
243
    public function delete(): ResponseInterface
244
    {
245
        $id = (int) $this->request->getParsedBody()['id'];
×
246
        try {
247
            $medlem = new Medlem($this->conn, $this->logger, $id);
×
248
            $medlem->delete();
×
249
            $this->updateEmailAliases();
×
250

251
            $this->logger->info('Medlem ' . $medlem->fornamn . ' ' . $medlem->efternamn . ' borttagen av: ' . Session::get('user_id'));
×
252
            // Set the URL and redirect
253
            return $this->redirectWithSuccess('medlem-list', 'Medlem borttagen!');
×
254
        } catch (Exception $e) {
×
255
            $this->logger->warning('Kunde inte ta bort medlem: ' . $e->getMessage());
×
256
            return $this->redirectWithError('medlem-list', 'Kunde inte ta bort medlem! Fel: ' . $e->getMessage());
×
257
        }
258
    }
259

260
    public function updateEmailAliases(): void
261
    {
262
        if ($this->app->getConfig('SMARTEREMAIL_ENABLED')) {
2✔
263
            $mailAlias = $this->app->getConfig('SMARTEREMAIL_ALIASNAME');
1✔
264
            $allEmails = array_column($this->medlemRepo->getEmailForActiveMembers(), 'email');
1✔
265

266
            $this->mailAliasService->updateAlias($mailAlias, $allEmails);
1✔
267
        }
268
    }
269
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc