v2.6.1d (Lyra): Plugin i18n, plugin editor vernieuwd, media invoegen

Plugin internationalisatie: plugins hebben eigen language/ mappen. Systeem
plugins volgen admin taal (admin.php), content plugins volgen content taal
(site.php). Fallback chain: geselecteerd -> plugin default_language -> CMS
default. PluginManager/AdminPluginAPI/CMSAPI uitgebreid met
getPluginTranslations()/t(). plugin.json settings ondersteunen
label_key/help_key/option_label_key.

Plugin uniformiteit: alle 6 plugins hebben uniforme structuur (README.md,
assets/.gitkeep, language/nl|en/). plugins/README.md herschreven.
guide plugin-development.md (NL+EN) volledig herschreven.

Plugin editor vernieuwd: geneste bestandsbrowser zijbalk, nieuw bestand
aanmaken, uploaden naar assets/, verwijderen en verplaatsen. Nieuwe routes:
plugins-file-upload, plugins-file-delete, plugins-file-move. Path-traversal
bescherming + protected plugins geblokkeerd.

Media invoegen in editor: nieuw /admin/media-list JSON endpoint + herbruikbare
_media-modal.twig include. Plugin-context scant assets/ map. editor-toolbar.js
modeMap uitgebreid voor css/scss/js/json.

Plugin overzicht knoppen: alleen iconen met title/aria-label.

Tests: pentest 30/30, WCAG 2.1 AA 25/25.
This commit is contained in:
2026-08-18 13:49:52 +00:00
parent 10c72de859
commit 5edc929c13
64 changed files with 3503 additions and 366 deletions
+63
View File
@@ -187,12 +187,71 @@ class AdminAuth
/**
* Get the role of the current user.
* Returns the override role if set (for testing), otherwise the real role.
*/
public function getCurrentRole(): string
{
if (isset($_SESSION['admin_role_override'])) {
return $_SESSION['admin_role_override'];
}
return $_SESSION['admin_role'] ?? 'admin';
}
/**
* Get the real role of the current user (ignoring any override).
*/
public function getRealRole(): string
{
return $_SESSION['admin_role'] ?? 'admin';
}
/**
* Check if the current user has an active role override.
*/
public function hasRoleOverride(): bool
{
return isset($_SESSION['admin_role_override']);
}
/**
* Temporarily switch to another role for testing purposes.
* Only admin users can do this; the override cannot grant more than admin.
*/
public function switchRole(string $role): array
{
if (!$this->isAuthenticated()) {
return ['success' => false, 'message' => 'Niet ingelogd.'];
}
// Only real admins can switch roles
$realRole = $this->getRealRole();
if ($realRole !== 'admin') {
return ['success' => false, 'message' => 'Alleen admins kunnen van rol wisselen.'];
}
if (!isset(self::ROLE_PERMISSIONS[$role])) {
return ['success' => false, 'message' => 'Ongeldige rol.'];
}
// Admins cannot switch to 'admin' (no point) — only to lower roles for testing
if ($role === 'admin') {
return ['success' => false, 'message' => 'Je bent al admin.'];
}
$_SESSION['admin_role_override'] = $role;
$this->log('info', "Rol-switch: {$_SESSION['admin_user']} -> {$role} (test)");
return ['success' => true, 'message' => 'Rol gewijzigd naar ' . self::getRoleLabel($role) . '.'];
}
/**
* Reset the role override back to the real admin role.
*/
public function resetRole(): array
{
if (isset($_SESSION['admin_role_override'])) {
unset($_SESSION['admin_role_override']);
$this->log('info', "Rol-switch gereset: {$_SESSION['admin_user']}");
return ['success' => true, 'message' => 'Rol teruggezet naar admin.'];
}
return ['success' => false, 'message' => 'Geen rol-override actief.'];
}
/**
* Check if the current user has permission to access a route.
*/
@@ -308,9 +367,13 @@ class AdminAuth
/**
* Change the role of an existing user.
* A user can never change their own role (security guard).
*/
public function changeRole(string $username, string $role): array
{
if ($username === ($_SESSION['admin_user'] ?? '')) {
return ['success' => false, 'message' => 'Je kunt je eigen rol niet wijzigen.'];
}
if (!isset(self::ROLE_PERMISSIONS[$role])) {
return ['success' => false, 'message' => 'Ongeldige rol.'];
}