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

klinge / sl-webapp / 18124637236

30 Sep 2025 09:04AM UTC coverage: 55.3% (+4.1%) from 51.199%
18124637236

push

github

web-flow
Merge pull request #101 from klinge/dependabot/composer/league/container-tw-5.1

Update league/container requirement from ^4.2 to ^5.1

1132 of 2047 relevant lines covered (55.3%)

2.12 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->app->getRouter()->generate('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 array $params The route parameters, must contain 'id'
94
     */
95
    public function edit(array $params): ResponseInterface
96
    {
97
        $id = (int) $params['id'];
×
98

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

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

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

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

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

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

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

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

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

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

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

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

264
            $this->mailAliasService->updateAlias($mailAlias, $allEmails);
1✔
265
        }
266
    }
267
}
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