From 5d978388f20c131857e40e72b607926757e10b0e Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:10:50 +0200 Subject: [PATCH 1/6] Only let users allowed to edit a member change its coordinates --- .../Controllers/MapsController.php | 57 +++--- .../tests/units/MapsController.php | 176 ++++++++++++++++++ 2 files changed, 203 insertions(+), 30 deletions(-) create mode 100644 tests/GaletteMaps/Controllers/tests/units/MapsController.php diff --git a/lib/GaletteMaps/Controllers/MapsController.php b/lib/GaletteMaps/Controllers/MapsController.php index 83a4b9b..2e78239 100644 --- a/lib/GaletteMaps/Controllers/MapsController.php +++ b/lib/GaletteMaps/Controllers/MapsController.php @@ -34,6 +34,20 @@ class MapsController extends AbstractPluginController #[Inject("Plugin Galette Maps")] protected array $module_info; + /** + * Member dependencies to load; groups are loaded on demand by access checks + * + * @return array + */ + private function getMemberDeps(): array + { + return [ + 'picture' => false, + 'groups' => false, + 'dues' => false + ]; + } + /** * Main route * @@ -82,12 +96,7 @@ public function localizeMember(Request $request, Response $response, ?int $id = if ($id === null) { $id = (int)$this->login->id; } - $deps = [ - 'picture' => false, - 'groups' => false, - 'dues' => false - ]; - $member = new Adherent($this->zdb, $id, $deps); + $member = new Adherent($this->zdb, $id, $this->getMemberDeps()); if ( $this->login->id != $id @@ -253,6 +262,7 @@ public function ILiveHere(Request $request, Response $response, ?int $id = null) { $error = null; $message = null; + $status = 200; if ($id === null && $this->login->isSuperAdmin()) { Analog::log( @@ -260,33 +270,18 @@ public function ILiveHere(Request $request, Response $response, ?int $id = null) Analog::INFO ); $error = _T('Superadmin cannot be localized.', 'maps'); - } elseif ($id === null) { - $member = new Adherent($this->zdb, $this->login->login); - $id = $member->id; - } elseif ( - !$this->login->isSuperAdmin() - && !$this->login->isAdmin() - && !$this->login->isStaff() - && $this->login->isGroupManager() - ) { - $member = new Adherent($this->zdb, $id); - //check if current logged-in user can manage loaded member - $groups = $member->groups; - $can_manage = false; - foreach ($groups as $group) { - if ($this->login->isGroupManager($group->getId())) { - $can_manage = true; - break; - } - } - if ($can_manage !== true) { + } else { + $id ??= (int)$this->login->id; + $member = new Adherent($this->zdb, $id, $this->getMemberDeps()); + if (!$member->canEdit($this->login)) { Analog::log( 'Logged in member ' . $this->login->login - . ' has tried to load member #' . $id - . ' but do not manage any groups he belongs to.', + . ' has tried to change coordinates of member #' . $id + . ' without the right to edit them.', Analog::WARNING ); - $error = _T('Coordinates has not been removed :(', 'maps'); + $error = _T('You do not have enough privileges.'); + $status = 403; } } @@ -320,7 +315,9 @@ public function ILiveHere(Request $request, Response $response, ?int $id = null) } } - $response = $response->withHeader('Content-type', 'application/json'); + $response = $response + ->withStatus($status) + ->withHeader('Content-type', 'application/json'); $res = [ 'res' => $error === null, diff --git a/tests/GaletteMaps/Controllers/tests/units/MapsController.php b/tests/GaletteMaps/Controllers/tests/units/MapsController.php new file mode 100644 index 0000000..9a53dcb --- /dev/null +++ b/tests/GaletteMaps/Controllers/tests/units/MapsController.php @@ -0,0 +1,176 @@ + + */ +class MapsController extends GaletteRoutingTestCase +{ + protected int $seed = 20260925143012; + protected bool $load_plugins = true; + + /** + * Cleanup after each test method + */ + public function tearDown(): void + { + $this->login->logout(); + $this->preferences->pref_bool_groupsmanagers_edit_member = false; + $this->zdb->execute($this->zdb->delete(MAPS_PREFIX . Coordinates::TABLE)); + parent::tearDown(); + } + + /** + * Log in given member + * + * @param array $mdata Member data + */ + private function logMember(array $mdata): void + { + $this->assertTrue($this->login->login($mdata['login_adh'], $mdata['mdp_adh'])); + } + + /** + * Make member two manager of a group + * + * @param Adherent[] $members Group members + */ + private function makeMemberTwoManager(array $members): void + { + $group = new \Galette\Entity\Group(); + $group->setName('Maps group'); + $this->assertTrue($group->store()); + $this->assertTrue($group->setManagers([$this->getMemberTwo()])); + $this->assertTrue($group->setMembers($members)); + } + + /** + * Post coordinates for a member + * + * @param ?int $id_adh Member ID, null for logged-in one + * @param array $data Posted data + */ + private function postCoords(?int $id_adh, array $data = ['latitude' => '50.362038', 'longitude' => '3.472998']): \Psr\Http\Message\ResponseInterface + { + $request = $this->createRequest( + 'maps_ilivehere', + $id_adh === null ? [] : ['id' => (string)$id_adh], + 'POST' + )->withParsedBody($data); + return $this->app->handle($request); + } + + /** + * Assert coordinates change has been refused + * + * @param \Psr\Http\Message\ResponseInterface $test_response Response + * @param int $id_adh Target member ID + */ + private function expectCoordsRefused(\Psr\Http\Message\ResponseInterface $test_response, int $id_adh): void + { + $this->assertSame(403, $test_response->getStatusCode()); + $this->assertSame( + ['res' => false, 'message' => 'You do not have enough privileges.'], + json_decode((string)$test_response->getBody(), true) + ); + $this->expectLogEntry( + Analog::WARNING, + 'has tried to change coordinates of member #' . $id_adh + ); + $this->expectNoLogEntry(); + } + + /** + * A member cannot change nor remove coordinates of another member + */ + public function testMemberCannotChangeOtherMemberCoords(): void + { + $member_one = $this->getMemberOne(); + $this->getMemberTwo(); + $coords = new Coordinates(); + $this->assertTrue($coords->setCoords($member_one->id, 48.85, 2.35)); + + $this->logMember($this->dataAdherentTwo()); + $this->expectCoordsRefused($this->postCoords($member_one->id), $member_one->id); + $this->expectCoordsRefused($this->postCoords($member_one->id, ['remove' => '1']), $member_one->id); + + $this->assertEquals( + ['id_adh' => $member_one->id, 'latitude' => '48.850000', 'longitude' => '2.350000'], + (array)$coords->getCoords($member_one->id) + ); + } + + /** + * A member can change its own coordinates, with or without its ID in the route + */ + public function testMemberChangesOwnCoords(): void + { + $member_one = $this->getMemberOne(); + $this->logMember($this->dataAdherentOne()); + + //storing the same position again reports a failure, hence a different latitude + foreach ([[null, '50.362038'], [$member_one->id, '51.5']] as [$id_adh, $latitude]) { + $test_response = $this->postCoords($id_adh, ['latitude' => $latitude, 'longitude' => '3.472998']); + $this->assertSame(200, $test_response->getStatusCode()); + $this->assertSame( + ['res' => true, 'message' => 'New coordinates has been stored!'], + json_decode((string)$test_response->getBody(), true) + ); + } + $this->assertCount(3, (array)(new Coordinates())->getCoords($member_one->id)); + } + + /** + * Group managers change coordinates of their members only when core allows them to edit members + */ + public function testManagerChangesCoordsAsCoreAllows(): void + { + $member_one = $this->getMemberOne(); + $this->makeMemberTwoManager([$member_one]); + $this->logMember($this->dataAdherentTwo()); + + $this->expectCoordsRefused($this->postCoords($member_one->id), $member_one->id); + $this->assertSame([], (new Coordinates())->getCoords($member_one->id)); + + $this->preferences->pref_bool_groupsmanagers_edit_member = true; + $test_response = $this->postCoords($member_one->id); + $this->assertSame(200, $test_response->getStatusCode()); + $this->assertCount(3, (array)(new Coordinates())->getCoords($member_one->id)); + } + + /** + * Superadmin changes coordinates of any member, but has none + */ + public function testSuperAdminCoords(): void + { + $member_one = $this->getMemberOne(); + $this->logSuperAdmin(); + + $test_response = $this->postCoords($member_one->id); + $this->assertSame(200, $test_response->getStatusCode()); + $this->assertCount(3, (array)(new Coordinates())->getCoords($member_one->id)); + + $test_response = $this->postCoords(null); + $this->assertSame( + ['res' => false, 'message' => 'Superadmin cannot be localized.'], + json_decode((string)$test_response->getBody(), true) + ); + $this->expectLogEntry(Analog::INFO, 'SuperAdmin does not live anywhere!'); + } +} From 932cade461e9c232e1c660b992148e3b758dde98 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:14:28 +0200 Subject: [PATCH 2/6] Only let users allowed to show a member display its coordinates --- .../Controllers/MapsController.php | 38 +++++----- templates/default/mymap.html.twig | 4 +- .../tests/units/MapsController.php | 71 ++++++++++++++++--- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lib/GaletteMaps/Controllers/MapsController.php b/lib/GaletteMaps/Controllers/MapsController.php index 2e78239..18d81f4 100644 --- a/lib/GaletteMaps/Controllers/MapsController.php +++ b/lib/GaletteMaps/Controllers/MapsController.php @@ -98,34 +98,27 @@ public function localizeMember(Request $request, Response $response, ?int $id = } $member = new Adherent($this->zdb, $id, $this->getMemberDeps()); - if ( - $this->login->id != $id - && !$this->login->isAdmin() - && !$this->login->isStaff() - && $this->login->isGroupManager() - ) { - //check if requested member is part of managed groups - $groups = $member->groups; - $is_managed = false; - foreach ($groups as $g) { - if ($this->login->isGroupManager($g->getId())) { - $is_managed = true; - break; - } - } - if ($is_managed !== true) { - //requested member is not part of managed groups, fall back to logged - //in member - //FIXME: silent fallback is maybe not the best to do - $member->load($this->login->id); - } + if (!$member->canShow($this->login)) { + Analog::log( + 'Logged in member ' . $this->login->login + . ' has tried to display coordinates of member #' . $id + . ' without the right to show them.', + Analog::WARNING + ); + return $this->redirectWithErrors( + response: $response, + errors: [_T("You do not have permission for requested URL.")], + redirect_url: $this->routeparser->urlFor('me') + ); } + $can_edit = $member->canEdit($this->login); $coords = new Coordinates(); $mcoords = $coords->getCoords($member->id); $towns = false; - if (count($mcoords) === 0) { + //towns are only proposed to choose a location + if ($can_edit && count($mcoords) === 0) { if ($member->town != '') { $t = new NominatimTowns($this->preferences); $towns = $t->search( @@ -142,6 +135,7 @@ public function localizeMember(Request $request, Response $response, ?int $id = _T('%member geographic position', 'maps') ), 'member' => $member, + 'can_edit' => $can_edit, 'require_dialog' => true, 'adh_map' => true, 'module_id' => $this->getModuleId(), diff --git a/templates/default/mymap.html.twig b/templates/default/mymap.html.twig index 123f3b6..62b1243 100644 --- a/templates/default/mymap.html.twig +++ b/templates/default/mymap.html.twig @@ -56,6 +56,7 @@ var _mapsBinded = function(map) { +{% if can_edit %} function onMapClick(e) { var popup = L.popup(); popup @@ -85,6 +86,7 @@ _a.data('latlng', e.popup._latlng); _iLiveHere(_a.attr('id')); }); +{% endif %} {% if town is defined %} @@ -150,7 +152,7 @@ }; L.marker([_lat, _lon], {icon: galetteIcon}).addTo(map) - .bindPopup('{{ member.sfullname|escape }}
{% if mymap is defined %}{{ _T("I live here!", "maps")|e("js") }}{% else %}{{ _T("Member lives here!", "maps")|e("js") }}{% endif %}
{{ _T("Remove")|e("js") }}').openPopup(); + .bindPopup('{{ member.sfullname|escape }}
{% if mymap is defined %}{{ _T("I live here!", "maps")|e("js") }}{% else %}{{ _T("Member lives here!", "maps")|e("js") }}{% endif %}{% if can_edit %}
{{ _T("Remove")|e("js") }}{% endif %}').openPopup(); {% else %} {# Town is not known. Show possibilities #} var _towns = $('#possible_towns'); diff --git a/tests/GaletteMaps/Controllers/tests/units/MapsController.php b/tests/GaletteMaps/Controllers/tests/units/MapsController.php index 9a53dcb..daa9f94 100644 --- a/tests/GaletteMaps/Controllers/tests/units/MapsController.php +++ b/tests/GaletteMaps/Controllers/tests/units/MapsController.php @@ -22,7 +22,7 @@ */ class MapsController extends GaletteRoutingTestCase { - protected int $seed = 20260925143012; + protected int $seed = 20260925101512; protected bool $load_plugins = true; /** @@ -101,18 +101,19 @@ private function expectCoordsRefused(\Psr\Http\Message\ResponseInterface $test_r */ public function testMemberCannotChangeOtherMemberCoords(): void { - $member_one = $this->getMemberOne(); - $this->getMemberTwo(); + //member two speaks Catalan, member one gets messages in English + $this->getMemberOne(); + $member_two = $this->getMemberTwo(); $coords = new Coordinates(); - $this->assertTrue($coords->setCoords($member_one->id, 48.85, 2.35)); + $this->assertTrue($coords->setCoords($member_two->id, 48.85, 2.35)); - $this->logMember($this->dataAdherentTwo()); - $this->expectCoordsRefused($this->postCoords($member_one->id), $member_one->id); - $this->expectCoordsRefused($this->postCoords($member_one->id, ['remove' => '1']), $member_one->id); + $this->logMember($this->dataAdherentOne()); + $this->expectCoordsRefused($this->postCoords($member_two->id), $member_two->id); + $this->expectCoordsRefused($this->postCoords($member_two->id, ['remove' => '1']), $member_two->id); $this->assertEquals( - ['id_adh' => $member_one->id, 'latitude' => '48.850000', 'longitude' => '2.350000'], - (array)$coords->getCoords($member_one->id) + ['id_adh' => $member_two->id, 'latitude' => '48.850000', 'longitude' => '2.350000'], + (array)$coords->getCoords($member_two->id) ); } @@ -154,6 +155,58 @@ public function testManagerChangesCoordsAsCoreAllows(): void $this->assertCount(3, (array)(new Coordinates())->getCoords($member_one->id)); } + /** + * A member cannot display coordinates of another member + */ + public function testMemberCannotShowOtherMemberCoords(): void + { + //member two speaks Catalan, member one gets messages in English + $this->getMemberOne(); + $member_two = $this->getMemberTwo(); + $this->assertTrue((new Coordinates())->setCoords($member_two->id, 48.85, 2.35)); + + $this->logMember($this->dataAdherentOne()); + $request = $this->createRequest('maps_localize_member', ['id' => (string)$member_two->id]); + $test_response = $this->app->handle($request); + $this->assertSame( + ['Location' => [$this->routeparser->urlFor('me')]], + $test_response->getHeaders() + ); + $this->assertSame(301, $test_response->getStatusCode()); + $this->expectFlashData(['error_detected' => ['You do not have permission for requested URL.']]); + $this->expectLogEntry( + Analog::WARNING, + 'has tried to display coordinates of member #' . $member_two->id + ); + $this->expectNoLogEntry(); + } + + /** + * Group managers display coordinates of their members, and change them only when core allows them to + */ + public function testManagerShowsCoords(): void + { + $member_one = $this->getMemberOne(); + $this->makeMemberTwoManager([$member_one]); + $this->assertTrue((new Coordinates())->setCoords($member_one->id, 48.85, 2.35)); + $this->logMember($this->dataAdherentTwo()); + + $request = $this->createRequest('maps_localize_member', ['id' => (string)$member_one->id]); + $test_response = $this->app->handle($request); + $this->assertSame(200, $test_response->getStatusCode()); + $body = (string)$test_response->getBody(); + $this->assertStringContainsString('48.850000', $body); + $this->assertStringNotContainsString('id="removecoords"', $body); + $this->assertStringNotContainsString('onMapClick', $body); + + $this->preferences->pref_bool_groupsmanagers_edit_member = true; + $test_response = $this->app->handle($request); + $this->assertSame(200, $test_response->getStatusCode()); + $body = (string)$test_response->getBody(); + $this->assertStringContainsString('id="removecoords"', $body); + $this->assertStringContainsString('onMapClick', $body); + } + /** * Superadmin changes coordinates of any member, but has none */ From fb219fb56f72c95db2e29e3c5e5d845573c17122 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:16:55 +0200 Subject: [PATCH 3/6] Escape members names for HTML in maps popups --- templates/default/maps.html.twig | 2 +- templates/default/mymap.html.twig | 2 +- .../tests/units/MapsController.php | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/templates/default/maps.html.twig b/templates/default/maps.html.twig index d4d85b5..2fa6b15 100644 --- a/templates/default/maps.html.twig +++ b/templates/default/maps.html.twig @@ -25,7 +25,7 @@ {% else %} {% set icon = 'galetteIcon' %} {% endif %} - _member = [{{ l.lat }}, {{ l.lng }}, {{ icon }}, '

{{ l.name|e("js") }}{% if l.nickname != '' %} {{ _T("aka", "maps")|e("js") }} {{ l.nickname|e("js") }}{% endif %}{% if l.company is defined %}
{{ l.company|e("js") }}{% endif %}

']; + _member = [{{ l.lat }}, {{ l.lng }}, {{ icon }}, '

{{ l.name|e|e("js") }}{% if l.nickname != '' %} {{ _T("aka", "maps")|e("js") }} {{ l.nickname|e|e("js") }}{% endif %}{% if l.company is defined %}
{{ l.company|e|e("js") }}{% endif %}

']; _markers.push(_member); {% endfor %} var _group = L.markerClusterGroup(); diff --git a/templates/default/mymap.html.twig b/templates/default/mymap.html.twig index 62b1243..a1e05a5 100644 --- a/templates/default/mymap.html.twig +++ b/templates/default/mymap.html.twig @@ -152,7 +152,7 @@ }; L.marker([_lat, _lon], {icon: galetteIcon}).addTo(map) - .bindPopup('{{ member.sfullname|escape }}
{% if mymap is defined %}{{ _T("I live here!", "maps")|e("js") }}{% else %}{{ _T("Member lives here!", "maps")|e("js") }}{% endif %}{% if can_edit %}
{{ _T("Remove")|e("js") }}{% endif %}').openPopup(); + .bindPopup('{{ member.sfullname|e|e("js") }}
{% if mymap is defined %}{{ _T("I live here!", "maps")|e("js") }}{% else %}{{ _T("Member lives here!", "maps")|e("js") }}{% endif %}{% if can_edit %}
{{ _T("Remove")|e("js") }}{% endif %}').openPopup(); {% else %} {# Town is not known. Show possibilities #} var _towns = $('#possible_towns'); diff --git a/tests/GaletteMaps/Controllers/tests/units/MapsController.php b/tests/GaletteMaps/Controllers/tests/units/MapsController.php index daa9f94..ab0e1a6 100644 --- a/tests/GaletteMaps/Controllers/tests/units/MapsController.php +++ b/tests/GaletteMaps/Controllers/tests/units/MapsController.php @@ -207,6 +207,34 @@ public function testManagerShowsCoords(): void $this->assertStringContainsString('onMapClick', $body); } + /** + * Nicknames and company names in map popups are not interpreted as HTML + * + * Member form strips tags, stored values may not have been through it. + * Names are safe anyway: Adherent::getNameWithCase() strips tags. + */ + public function testMapEscapesNames(): void + { + $member_one = $this->getMemberOne(); + $update = $this->zdb->update(Adherent::TABLE); + $update->set([ + 'pseudo_adh' => 'nick', + 'societe_adh' => '', + ])->where([Adherent::PK => $member_one->id]); + $this->zdb->execute($update); + $this->assertTrue((new Coordinates())->setCoords($member_one->id, 48.85, 2.35)); + + $this->logSuperAdmin(); + $test_response = $this->app->handle($this->createRequest('maps_map')); + $this->assertSame(200, $test_response->getStatusCode()); + $body = (string)$test_response->getBody(); + //a JS escaped "<" would be turned back into markup by the popup + $this->assertStringNotContainsString('\u003Cb\u003E', $body); + $this->assertStringNotContainsString('\u003Cimg', $body); + $this->assertStringContainsString('\u0026lt\u003Bb\u0026gt\u003Bnick', $body); + $this->assertStringContainsString('\u0026lt\u003Bimg\u0020src', $body); + } + /** * Superadmin changes coordinates of any member, but has none */ From 20b1b13b43ef9eac50dcc841863ccc2c2e69aba1 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:17:49 +0200 Subject: [PATCH 4/6] Load only displayed members columns for the map --- lib/GaletteMaps/Coordinates.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/GaletteMaps/Coordinates.php b/lib/GaletteMaps/Coordinates.php index 2ffc984..067ab5a 100644 --- a/lib/GaletteMaps/Coordinates.php +++ b/lib/GaletteMaps/Coordinates.php @@ -84,7 +84,9 @@ public function listCoords(): array [ 'a' => PREFIX_DB . Adherent::TABLE ], - 'a.' . self::PK . '=' . 'c.' . self::PK + 'a.' . self::PK . '=' . 'c.' . self::PK, + //only what the map displays + ['nom_adh', 'prenom_adh', 'pseudo_adh', 'societe_adh'] )->where->equalTo( 'activite_adh', new Expression('true') @@ -145,16 +147,15 @@ public function listCoords(): array $res = []; foreach ($results as $r) { - $a = new Adherent($zdb, $r); $m = [ - 'id_adh' => $a->id, + 'id_adh' => (int)$r->{self::PK}, 'lat' => $r->latitude, 'lng' => $r->longitude, - 'name' => $a->sname, - 'nickname' => $a->nickname + 'name' => Adherent::getNameWithCase($r->nom_adh, $r->prenom_adh), + 'nickname' => $r->pseudo_adh ]; - if ($a->isCompany()) { - $m['company'] = $a->company_name; + if (trim($r->societe_adh ?? '') !== '') { + $m['company'] = $r->societe_adh; } $res[] = $m; } From 5bf11a66472b729922ce3b545741451a6167e34f Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:20:44 +0200 Subject: [PATCH 5/6] Refuse coordinates changes with a message core translates --- lib/GaletteMaps/Controllers/MapsController.php | 2 +- tests/GaletteMaps/Controllers/tests/units/MapsController.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/GaletteMaps/Controllers/MapsController.php b/lib/GaletteMaps/Controllers/MapsController.php index 18d81f4..4d1240f 100644 --- a/lib/GaletteMaps/Controllers/MapsController.php +++ b/lib/GaletteMaps/Controllers/MapsController.php @@ -274,7 +274,7 @@ public function ILiveHere(Request $request, Response $response, ?int $id = null) . ' without the right to edit them.', Analog::WARNING ); - $error = _T('You do not have enough privileges.'); + $error = _T('You do not have permission for requested URL.'); $status = 403; } } diff --git a/tests/GaletteMaps/Controllers/tests/units/MapsController.php b/tests/GaletteMaps/Controllers/tests/units/MapsController.php index ab0e1a6..321d060 100644 --- a/tests/GaletteMaps/Controllers/tests/units/MapsController.php +++ b/tests/GaletteMaps/Controllers/tests/units/MapsController.php @@ -86,7 +86,8 @@ private function expectCoordsRefused(\Psr\Http\Message\ResponseInterface $test_r { $this->assertSame(403, $test_response->getStatusCode()); $this->assertSame( - ['res' => false, 'message' => 'You do not have enough privileges.'], + //message comes in the language of the logged-in member + ['res' => false, 'message' => _T('You do not have permission for requested URL.')], json_decode((string)$test_response->getBody(), true) ); $this->expectLogEntry( From 464d4cc0010329469b3a6ff23e84701712baeef6 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Fri, 25 Sep 2026 07:59:09 +0200 Subject: [PATCH 6/6] Get flash messages from their class name in the container --- _routes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_routes.php b/_routes.php index 6436a4d..158349b 100644 --- a/_routes.php +++ b/_routes.php @@ -17,7 +17,7 @@ $check_js_middleware = function (\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Server\RequestHandlerInterface $handler) use ($container) { //check if JS has been generated if (!file_exists(__DIR__ . '/webroot/maps-main.bundle.min.js')) { - $container->get('flash')->addMessageNow( + $container->get(\Slim\Flash\Messages::class)->addMessageNow( 'error_detected', _T('Javascript libraries has not been built!', 'maps') );