v2.6.5 (Lyra): Dynamische pad-resolutie, WordPress-stijl docblocks, security-fix wachtwoord, git-historie schoon

- Bug: dashboard toonde 0 content (AdminPluginAPI::getContentDir() gaf relatief pad terug zonder normalisatie)
- Dynamische pad-resolutie: PluginAPIInterface uitgebreid met getProjectRoot/getContentDir/getPluginsDir/getVersionInfo; CMSAPI en AdminPluginAPI implementeren deze universeel
- public/index.php media-serving gebruikt $config['content_dir'] i.p.v. hardcoded /content
- Navigation en Logs plugins halen paden via de API i.p.v. hardcoded dirname(__DIR__)
- WordPress-stijl docblocks toegevoegd voor alle classes, methods, properties en functies (~450 docblocks, @since 2.6.5)
- Security: hardcoded plaintext-wachtwoord 'admin' verwijderd uit AdminAuth.php; bij eerste installatie wordt een cryptografisch veilig wachtwoord gegenereerd (random_bytes, 16 tekens) en eenmalig op het inlogscherm getoond
- Security: git-geschiedenis schoongemaakt (admin.json, admin.json.example, admin-console/config/admin.json verwijderd uit alle commits; filter-branch over alle branches + tags, gc --prune --aggressive)
- README.md, README.en.md, AGENTS.md bijgewerkt
- Test-scripts bijgewerkt naar clean-URL structuur + actuele ARIA-waarden
- Versie verhoogd naar 2.6.5
- Tests: pentest 29/29, WCAG 25/25, functioneel 16/16, enhanced 25/25
This commit is contained in:
2026-08-27 09:05:51 +00:00
parent 74612aefbb
commit d9ea2eee47
38 changed files with 771 additions and 572 deletions
+82 -82
View File
@@ -79,7 +79,7 @@ $twig->addFunction(new \Twig\TwigFunction('role_label', function($role) {
* taalbestand niet bestaat of geen array teruggeeft, valt de functie terug
* op de Nederlandse vertalingen.
*
* @since 2.6.4
* @since 2.6.5
*
* @param array|null $siteConfig Site-configuratie array met admin_language en language.default.
* @return array<string,string> Vertaal-string map (key => vertaling). Leeg indien geen bestand gevonden.
@@ -155,7 +155,7 @@ $route = $_GET['route'] ?? '';
* van dat thema naar een `header_color`. Wanneer het thema of de kleur
* ontbreekt, wordt de standaardkleur `#0a369d` teruggegeven.
*
* @since 2.6.4
* @since 2.6.5
*
* @param array $config App-configuratie array met de sleutel `config_json`.
* @return string CSS-kleurwaarde (bijv. '#0a369d').
@@ -177,7 +177,7 @@ function getSidebarColor($config) {
/**
* Geeft de lijst van beschermde plugins die niet uitgeschakeld of verwijderd mogen worden.
*
* @since 2.6.4
* @since 2.6.5
*
* @return array<int,string> Namen van beschermde plugins (bijv. ['Navigation']).
*/
@@ -189,7 +189,7 @@ function getProtectedPlugins(): array {
/**
* Controleert of een pluginnaam op de lijst van beschermde plugins staat.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $pluginName Naam van de plugin om te controleren.
* @return bool True wanneer de plugin beschermd is, anders false.
@@ -210,7 +210,7 @@ function isProtectedPlugin(string $pluginName): bool {
* 2. plugin.json 'type' override
* 3. regex uit <Plugin>.php 'type' => '...' (fallback als plugin.json geen type bevat)
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $pluginsDir Absoluut pad naar de plugins-directory.
* @return array<int,array{name:string,title:string,type:string}> Uitsluitend content-type plugins.
@@ -602,7 +602,7 @@ switch ($route) {
* Toont o.a. het aantal pagina's, mappen, content-grootte, PHP/CMS-versie
* en een overzicht van alle plugins met hun ingeschakelde status.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, plugins_dir, config_json).
@@ -672,7 +672,7 @@ function handleDashboard($auth, $config, $twig, $user, $csrf, $siteConfig): void
* hoe de interface eruitziet met die rol. Verwacht een geldige CSRF-token
* en een `new_role` POST-veld; stuur daarna door naar het dashboard.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (voor logging).
@@ -705,7 +705,7 @@ function handleRoleSwitch($auth, $config): void
* override ongedaan maken en terugkeren naar de echte rol. Verwacht een
* geldige CSRF-token en stuurt daarna door naar het dashboard.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (voor logging).
@@ -738,7 +738,7 @@ function handleRoleReset($auth, $config): void
* ondersteuning voor uploaden van bestanden (POST). Bevat path-traversal
* bescherming via str_replace en trim.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -838,7 +838,7 @@ function handleContent($auth, $config, $twig, $user, $csrf, $siteConfig): void
* bestandsnamen (content gebruikt taal-prefix in bestandsnamen, anders dan
* plugins/themes).
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, plugins_dir).
@@ -1303,7 +1303,7 @@ function handleContentFiles($auth, $config, $twig, $user, $csrf, $siteConfig): v
* afbeeldingen, video, audio, pdf, zip, office-docs, css, scss, js, json, html, md.
* Bevat path-traversal bescherming via realpath + prefix-check op content_dir.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1408,7 +1408,7 @@ function handleContentFileUpload($auth, $config, $user): void
* Weigert mappen, dotfiles en paden die buiten content_dir vallen. Na
* verwijdering wordt terugverwezen naar de map waar het bestand in stond.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1480,7 +1480,7 @@ function handleContentFileDelete($auth, $config, $user): void
* (GET) met een dropdown van beschikbare mappen en voert de hernoemactie (move)
* uit op POST. Optioneel kan de bestandsnaam worden gewijzigd (extensie behouden).
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1620,7 +1620,7 @@ function handleContentFileMove($auth, $config, $twig, $user, $csrf): void
* Variant van handleContentDirCreate die terugverwijst naar content-files
* (de verenigde content-editor). Alleen POST met een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1676,7 +1676,7 @@ function handleContentDirCreateIn($auth, $config, $user): void
* Variant van handleContentDirRename die terugverwijst naar content-files.
* Toont een hernoem-formulier (GET) en voert de hernoemactie uit op POST.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1768,7 +1768,7 @@ function handleContentDirRenameIn($auth, $config, $twig, $user, $csrf): void
* Alleen lege mappen mogen verwijderd worden (verborgen .bak bestanden worden
* genegeerd bij de leegte-check). Alleen POST met een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -1840,7 +1840,7 @@ function handleContentDirDeleteIn($auth, $config, $user): void
* op (POST). Frontmatter (layout/plugins/edited) wordt bijgewerkt bij opslaan.
* Bevat path-traversal bescherming via realpath + prefix-check.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, plugins_dir).
@@ -1985,7 +1985,7 @@ function handleContentEdit($auth, $config, $twig, $user, $csrf, $siteConfig): vo
* (layout/created/edited) en een stub, waarna wordt doorverwezen naar de
* content-editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2088,7 +2088,7 @@ function handleContentNew($auth, $config, $twig, $user, $csrf, $siteConfig): voi
* Verwacht een geldige CSRF-token en een `file` POST/GET-veld. Na verwijderen
* wordt doorverwezen naar de map waar het bestand in stond.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2128,7 +2128,7 @@ function handleContentDelete($auth, $config): void
* CSRF-token en een `dirname` POST-veld. Na aanmaken wordt terugverwezen
* naar de content-lijst.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2171,7 +2171,7 @@ function handleContentDirCreate($auth, $config): void
* Toont een hernoem-formulier (GET) en voert de hernoemactie uit op POST.
* Na succesvolle hernoeming wordt doorverwezen naar de hernoemde map.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2235,7 +2235,7 @@ function handleContentDirRename($auth, $config, $twig, $user, $csrf): void
* Verwacht een geldige CSRF-token en verwijdert de map alleen als deze
* leeg is. Na verwijderen wordt terugverwezen naar de bovenliggende map.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2279,7 +2279,7 @@ function handleContentDirDelete($auth, $config): void
* doelmappen en voert de verplaatsactie uit op POST. Na succes wordt
* doorverwezen naar de doelmap.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -2370,7 +2370,7 @@ function handleContentMove($auth, $config, $twig, $user, $csrf): void
* Op POST met actie `download_zip` wordt een ZIP-backup van content gemaakt
* en direct als download aangeboden.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, codepress_root).
@@ -2452,7 +2452,7 @@ function handleContentBackup($auth, $config, $twig, $user, $csrf): void
* ContentBackup::restoreFromZip aan en stuurt daarna door naar de
* backup-pagina met een statusmelding.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, codepress_root).
@@ -2499,7 +2499,7 @@ function handleContentRestore($auth, $config): void
* Verwacht een geldige CSRF-token en roept ContentBackup::gitInit aan.
* Na afloop wordt doorverwezen naar de backup-pagina met een statusmelding.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, codepress_root).
@@ -2536,7 +2536,7 @@ function handleContentGitInit($auth, $config): void
* Verwacht een geldige CSRF-token en een `commit_message` POST-veld. Roept
* ContentBackup::gitCommit aan en stuurt daarna door naar de backup-pagina.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, codepress_root).
@@ -2574,7 +2574,7 @@ function handleContentGitCommit($auth, $config): void
* Verwacht een geldige CSRF-token en een `commit` POST-veld met de commit-hash.
* Roept ContentBackup::gitRestore aan en stuurt daarna door naar de backup-pagina.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, codepress_root).
@@ -2612,7 +2612,7 @@ function handleContentGitRestore($auth, $config): void
* in config.json. Op succes wordt via PRG doorgestuurd zodat de nieuwe
* admin-taal direct wordt toegepast.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (config_json, content_dir).
@@ -2689,7 +2689,7 @@ function handleConfig($auth, $config, $twig, $user, $csrf): void
* admin-config JSON. Op POST (met geldige CSRF-token) worden de waarden
* opgeslagen en bevestigd.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (admin_config).
@@ -2742,7 +2742,7 @@ function handleSecurity($auth, $config, $twig, $user, $csrf): void
* Toont per thema de naam, of deze actief/beschermd is, SCSS-compile status
* en -mtimes. Actieve thema's worden eerst getoond, daarna alfabetisch.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -2819,7 +2819,7 @@ function handleTheme($auth, $config, $twig, $user, $csrf, $siteConfig): void
* op een bestaand thema (kopiëren) of met een lege uniforme structuur. Op
* succes wordt doorverwezen naar de thema-editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -2908,7 +2908,7 @@ function handleThemeNew($auth, $config, $twig, $user, $csrf): void
/**
* Maakt een uniforme thema-structuur aan (theme.json, layouts, partials, assets/scss, etc.).
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $themeDir Absoluut pad naar de nieuwe thema-map (al aangemaakt).
* @param string $themeName Opgeschoonde thema-naam.
@@ -2965,7 +2965,7 @@ function createUniformThemeStructure(string $themeDir, string $themeName): void
*
* Slaat css_compiled/ (runtime-artefact) en .git/.gitkeep over.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $src Bron-directory (absoluut).
* @param string $dst Doel-directory (absoluut, bestaat al).
@@ -3000,7 +3000,7 @@ function copyDirRecursive(string $src, string $dst): void
/**
* Verwijdert een directory recursief (gebruikt door theme-delete).
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $dir Te verwijderen directory (absoluut).
* @return void
@@ -3030,7 +3030,7 @@ function removeDirRecursive(string $dir): void
* via realpath + prefix-check. Het default-thema kan wel bewerkt worden (geen
* protected block), maar verwijderen/activeren is geblokkeerd.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -3277,7 +3277,7 @@ function handleThemeEdit($auth, $config, $twig, $user, $csrf): void
* audio, pdf, css, scss, js, json, html, md, twig, fonts. Bevat path-traversal
* bescherming via realpath + prefix-check op de thema assets-map.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -3387,7 +3387,7 @@ function handleThemeFileUpload($auth, $config, $user): void
* Weigert mappen, dotfiles, theme.json en paden die buiten de thema-map
* vallen. Na verwijderen wordt terugverwezen naar theme.json in de editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -3468,7 +3468,7 @@ function handleThemeFileDelete($auth, $config, $user): void
* dropdown van beschikbare mappen en voert de hernoemactie (move) uit op POST.
* theme.json kan niet verplaatst worden.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -3601,7 +3601,7 @@ function handleThemeFileMove($auth, $config, $twig, $user, $csrf): void
* Verwacht een geldige CSRF-token en een `theme` POST-veld. Het thema moet
* bestaan. Na activeren wordt terugverwezen naar het thema-overzicht.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (config_json).
@@ -3647,7 +3647,7 @@ function handleThemeActivate($auth, $config, $user): void
* Alleen niet-actieve, niet-default thema's mogen verwijderd worden. Na
* verwijderen wordt terugverwezen naar het thema-overzicht met een melding.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (config_json).
@@ -3700,7 +3700,7 @@ function handleThemeDelete($auth, $config, $user): void
* Verwacht een geldige CSRF-token en een `theme` POST-veld. Na compilatie
* wordt terugverwezen naar het thema-overzicht met een statusmelding.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -3772,7 +3772,7 @@ function handleThemeScss($auth, $config, $user): void
* type (content/system). Plugin-type wordt bepaald uit plugin.json of de
* plugin PHP-bron.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir, config_json).
@@ -3837,7 +3837,7 @@ function handlePlugins($auth, $config, $twig, $user, $csrf): void
* plugin.json en een PHP-stub. Op succes wordt doorverwezen naar de
* plugin-editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -3905,7 +3905,7 @@ function handlePluginsNew($auth, $config, $twig, $user, $csrf): void
* map aanmaken. Beschermde plugins kunnen niet bewerkt worden. Bevat
* path-traversal bescherming via realpath + prefix-check.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4163,7 +4163,7 @@ function handlePluginsEdit($auth, $config, $twig, $user, $csrf): void
* doelmap moet binnen de echte plugin assets-map liggen. Beschermde plugins
* worden geblokkeerd.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4268,7 +4268,7 @@ function handlePluginsFileUpload($auth, $config, $user): void
* verwijderen wordt terugverwezen naar het hoofdpluginbestand. Beschermde
* plugins worden geblokkeerd.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4349,7 +4349,7 @@ function handlePluginsFileDelete($auth, $config, $user): void
* bron en doel moeten beide binnen de echte plugin-map vallen. Beschermde
* plugins worden geblokkeerd.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4484,7 +4484,7 @@ function handlePluginsFileMove($auth, $config, $twig, $user, $csrf): void
* Spiegelt handleContentDirCreateIn. Alleen POST met een geldige CSRF-token.
* Na aanmaken wordt doorverwezen naar de nieuwe map in de thema-editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -4548,7 +4548,7 @@ function handleThemeDirCreateIn($auth, $config, $user): void
* voert de hernoemactie uit op POST. Na succes wordt doorverwezen naar de
* hernoemde map.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -4645,7 +4645,7 @@ function handleThemeDirRenameIn($auth, $config, $twig, $user, $csrf): void
* Spiegelt handleContentDirDeleteIn. Alleen lege mappen mogen verwijderd
* worden. Alleen POST met een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -4718,7 +4718,7 @@ function handleThemeDirDeleteIn($auth, $config, $user): void
* Alleen POST met een geldige CSRF-token. Na aanmaken wordt doorverwezen naar
* de nieuwe map in de plugin-editor.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4782,7 +4782,7 @@ function handlePluginsDirCreateIn($auth, $config, $user): void
* Toont een hernoem-formulier (GET) en voert de hernoemactie uit op POST. Na
* succes wordt doorverwezen naar de hernoemde map.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4880,7 +4880,7 @@ function handlePluginsDirRenameIn($auth, $config, $twig, $user, $csrf): void
* worden. Beschermde plugins worden geblokkeerd. Alleen POST met een geldige
* CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -4952,7 +4952,7 @@ function handlePluginsDirDeleteIn($auth, $config, $user): void
* Accepteert: scope (content|theme|plugin), source (relatief pad) en
* destination (relatieve map). Retourneert JSON: {ok, message, newPath?, redirect?}.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, plugins_dir).
@@ -5068,7 +5068,7 @@ function handleTreeMove($auth, $config, $user): void
* config.json van de plugin. Op POST worden de waarden opgeslagen. Setting-
* labels/helpteksten worden via plugin-vertalingen opgelost.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir, config_json).
@@ -5195,7 +5195,7 @@ function handlePluginsConfig($auth, $config, $twig, $user, $csrf): void
* Beschermde plugins kunnen niet uitgeschakeld worden. Verwacht een geldige
* CSRF-token en een `plugin` POST-veld.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (config_json).
@@ -5250,7 +5250,7 @@ function handlePluginsToggle($auth, $config): void
* CSRF-token en een `plugin` POST-veld. Na verwijderen wordt terugverwezen
* naar het plugin-overzicht.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (plugins_dir).
@@ -5310,7 +5310,7 @@ function handlePluginsDelete($auth, $config): void
* Toont alle gebruikers met zoek- en rolfilters. Op POST kan een gebruiker
* verwijderd of van rol gewisseld worden. Verwacht een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -5394,7 +5394,7 @@ function handleUsers($auth, $config, $twig, $user, $csrf): void
* wachtwoord-wijziging (alleen als de echte rol admin is) en verwijderen.
* Een gebruiker kan zichzelf niet verwijderen. Verwacht een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -5495,7 +5495,7 @@ function handleUsersEdit($auth, $config, $twig, $user, $csrf): void
* wachtwoord, rol, email en auteur-gegevens. Op succes wordt doorverwezen
* naar de gebruiker-bewerkpagina. Verwacht een geldige CSRF-token.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -5553,7 +5553,7 @@ function handleUsersNew($auth, $config, $twig, $user, $csrf): void
* navigatie-zijbalk (via de Navigation plugin). Valt terug op Engels indien
* de gevraagde taal niet bestaat.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -5662,7 +5662,7 @@ function handleGuide($auth, $config, $twig, $user, $csrf): void
* Leest de huidige versie uit version.php en controleert of de .git-map
* schrijfbaar is voor eventuele updates.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array.
@@ -5699,7 +5699,7 @@ function handleUpdate($auth, $config, $twig, $user, $csrf): void
* Toont een lijst van bestanden en mappen in de opgegeven subdir. Bevat
* path-traversal bescherming via str_replace.
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir).
@@ -5745,7 +5745,7 @@ function handleMedia($auth, $config, $twig, $user, $csrf): void
* Path-traversal bescherming: elk opgelost pad moet beginnen met de opgeloste
* basismap (content-, plugin-assets- of theme-assets-map).
*
* @since 2.6.4
* @since 2.6.5
*
* @param AdminAuth $auth Authenticatie-object.
* @param array $config App-configuratie array (content_dir, plugins_dir).
@@ -5834,7 +5834,7 @@ function handleMediaList($auth, $config): void
/**
* Schrijft een admin-logregel naar het logbestand en (indien beschikbaar) LogManager.
*
* @since 2.6.4
* @since 2.6.5
*
* @param array $config App-configuratie array met de sleutel `log_file`.
* @param string $level Logniveau (bijv. 'info', 'warning', 'error').
@@ -5860,7 +5860,7 @@ function adminLog(array $config, string $level, string $message): void
/**
* Telt recursief het aantal bestanden in een directory, optioneel gefilterd op extensies.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $dir Te scannen directory (absoluut).
* @param string[] $extensions Toegestane extensies (zonder punt). Leeg = alle bestanden.
@@ -5887,7 +5887,7 @@ function countFiles(string $dir, array $extensions = []): int
/**
* Telt recursief het aantal mappen in een directory, exclusief dotfiles.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $dir Te scannen directory (absoluut).
* @return int Aantal gevonden mappen. 0 wanneer de dir niet bestaat.
@@ -5912,7 +5912,7 @@ function countDirs(string $dir): int
/**
* Telt het aantal ingeschakelde plugins in de site-config.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $pluginsDir Plugins-directory (ongebruikt, voor compatibiliteit).
* @param string $configJson Pad naar config.json.
@@ -5928,7 +5928,7 @@ function countEnabledPlugins(string $pluginsDir, string $configJson): int
/**
* Berekent recursief de totale bestandsgrootte (in bytes) van een directory.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $dir Te scannen directory (absoluut).
* @return int Totale grootte in bytes. 0 wanneer de dir niet bestaat.
@@ -5952,7 +5952,7 @@ function dirSize(string $dir): int
/**
* Formatteert een byte-grootte naar een leesbare string (B/KB/MB/GB/TB).
*
* @since 2.6.4
* @since 2.6.5
*
* @param int $bytes Aantal bytes.
* @return string Geformatteerde grootte met eenheid (bijv. '1.5 MB').
@@ -5974,7 +5974,7 @@ function formatSize(int $bytes): string
* Toont per item de naam, pad, of het een map is, extensie, grootte en
* wijzigingsdatum. Mappen worden eerst getoond, daarna bestanden alfabetisch.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $fullPath Absoluut pad van de te scannen map.
* @param string $subdir Relatieve subdir binnen content (voor pad-berekening).
@@ -6035,7 +6035,7 @@ function scanContentDir(string $fullPath, string $subdir): array
* wordt gebruikt; de echte basismap is het anker en elk opgelost kindpad wordt
* gecontroleerd om daarbinnen te blijven.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $dir Absoluut pad naar de te scannen directory.
* @param string $scope Een van: 'plugin', 'theme', 'content'. Default 'plugin'.
@@ -6058,7 +6058,7 @@ function scanEditorFiles(string $dir, string $scope = 'plugin'): array
/**
* Recursieve helper voor scanEditorFiles(). Bouwt één niveau van de boom.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $absDir Absoluut pad van de te scannen directory.
* @param string $relPath Relatief pad van $absDir binnen de basis (leeg voor root).
@@ -6144,7 +6144,7 @@ function scanEditorFilesNode(string $absDir, string $relPath, string $realBase,
/**
* Scant de bestandsboom van een plugin-directory.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $pluginDir Absoluut pad naar de plugin-directory.
* @return array<int,array<string,mixed>> Geneste bestandsboom.
@@ -6157,7 +6157,7 @@ function scanPluginFiles(string $pluginDir): array
/**
* Scant de bestandsboom van een thema-directory.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $themeDir Absoluut pad naar de thema-directory.
* @return array<int,array<string,mixed>> Geneste bestandsboom.
@@ -6170,7 +6170,7 @@ function scanThemeFiles(string $themeDir): array
/**
* Scant de bestandsboom van een content-directory.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $contentDir Absoluut pad naar de content-directory.
* @return array<int,array<string,mixed>> Geneste bestandsboom.
@@ -6187,7 +6187,7 @@ function scanContentFiles(string $contentDir): array
* sleutel. Mappen worden meegenomen als ze content bevatten (vertegenwoordigd
* door hun pad).
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $contentDir Absoluut pad naar de content-directory.
* @return array<string,string> Gesorteerde lijst van [pageKey => displayLabel].
@@ -6262,7 +6262,7 @@ function collectContentPages(string $contentDir): array
/**
* Werkt een frontmatter-sleutel bij in content of voegt deze toe.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $content Content met optionele --- frontmatter.
* @param string $key Frontmatter-sleutel om bij te werken.
@@ -6298,7 +6298,7 @@ function updateContentFrontmatter(string $content, string $key, string $value):
/**
* Leest een enkele waarde uit de frontmatter van content.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $content Content met optionele --- frontmatter.
* @param string $key Frontmatter-sleutel om te lezen.
@@ -6318,7 +6318,7 @@ function extractFrontmatterValue(string $content, string $key): string
/**
* Bepaalt de taal-prefix van een bestandsnaam (bijv. 'nl' voor 'nl.test.md').
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $file Bestandsnaam of -pad.
* @return string Taalcode ('nl', 'en', 'de', 'fr', 'es') of 'nl' als standaard.
@@ -6338,7 +6338,7 @@ function extractLanguagePrefix(string $file): string
*
* Kopieert het bestand naar <dirname>/.bak/<basename>.<timestamp>.
*
* @since 2.6.4
* @since 2.6.5
*
* @param string $filePath Absoluut pad naar het te backuppen bestand.
* @return void
+5 -5
View File
@@ -8,7 +8,7 @@
* /plugins/ URLs naar dit bestand. Paden worden via realpath() + prefix-
* check afgedwongen binnen de juiste asset-map om path traversal te voorkomen.
*
* @since 2.6.4
* @since 2.6.5
* @package CodePress
*/
/**
@@ -40,7 +40,7 @@ $assetFile = null;
/**
* /themes/<naam>/assets/...: theme-asset matchen en pad oplossen.
*
* @since 2.6.4
* @since 2.6.5
*/
// /themes/<name>/assets/...
if (preg_match('#^/themes/([^/]+)/assets/(.+)$#', $path, $m)) {
@@ -52,7 +52,7 @@ if (preg_match('#^/themes/([^/]+)/assets/(.+)$#', $path, $m)) {
/**
* /admin/assets/...: admin-theme-asset matchen (default admin theme).
*
* @since 2.6.4
* @since 2.6.5
*/
// /admin/assets/...
elseif (preg_match('#^/admin/assets/(.+)$#', $path, $m)) {
@@ -63,7 +63,7 @@ elseif (preg_match('#^/admin/assets/(.+)$#', $path, $m)) {
/**
* /plugins/<naam>/assets/...: plugin-asset matchen en pad oplossen.
*
* @since 2.6.4
* @since 2.6.5
*/
// /plugins/<name>/assets/...
elseif (preg_match('#^/plugins/([^/]+)/assets/(.+)$#', $path, $m)) {
@@ -79,7 +79,7 @@ elseif (preg_match('#^/plugins/([^/]+)/assets/(.+)$#', $path, $m)) {
* Controleert dat het opgeloste pad binnen de asset-map blijft en een
* regulier bestand is; anders volgt een 404.
*
* @since 2.6.4
* @since 2.6.5
*/
if ($assetFile && $realBase) {
$realFile = realpath($assetFile);
+13 -13
View File
@@ -8,7 +8,7 @@
* controles uit, registreert analytics- en logvermeldingen en render
* uiteindelijk de pagina via CodePressCMS::render().
*
* @since 2.6.4
* @since 2.6.5
* @package CodePress
*/
require_once __DIR__ . '/../cms/core/index.php';
@@ -18,7 +18,7 @@ $config = include __DIR__ . '/../cms/core/config.php';
/**
* Log-systeem initialiseren op basis van de logging-configuratie.
*
* @since 2.6.4
* @since 2.6.5
*/
// Initialize dynamic logging
LogManager::init($config['logging'] ?? []);
@@ -26,7 +26,7 @@ LogManager::init($config['logging'] ?? []);
/**
* Security headers instellen voor alle front-end responses.
*
* @since 2.6.4
* @since 2.6.5
*/
// Security headers
header('X-Content-Type-Options: nosniff');
@@ -43,7 +43,7 @@ header_remove('X-Powered-By');
* content-map dynamisch op basis van config['content_dir'] en serveert
* bestanden buiten public/ met een pad-controle om traversal te blokkeren.
*
* @since 2.6.4
* @since 2.6.5
*/
// Serve media files from any content/ subdirectory via /-media/
// Serve files from content/-assets/ via /-assets/ (backward compatible)
@@ -88,7 +88,7 @@ if (strpos($path, '/-media/') === 0) {
* /-assets/ route: serveert bestanden uit content/-assets/ of de content-
* root, met backward-compatibiliteit en path-traversal-controle.
*
* @since 2.6.4
* @since 2.6.5
*/
if (strpos($path, '/-assets/') === 0) {
$relative = ltrim(substr($path, 8), '/');
@@ -136,7 +136,7 @@ if ($path === '/robots.txt') {
*
* Voorkomt dat ruwe content-bestanden via het web opgevraagd worden.
*
* @since 2.6.4
* @since 2.6.5
*/
// Block direct access to content files
if (strpos($path, '/content/') === 0) {
@@ -153,7 +153,7 @@ if (strpos($path, '/content/') === 0) {
* slaan de controles over. Het requestStatus wordt bijgehouden voor
* latere logging en blocking.
*
* @since 2.6.4
* @since 2.6.5
*/
// Load RequestLogger for IP & request logging
require_once __DIR__ . '/../cms/core/class/RequestLogger.php';
@@ -208,7 +208,7 @@ if (!$isAllowedIp) {
/**
* CMS-instantie aanmaken met de geladen configuratie.
*
* @since 2.6.4
* @since 2.6.5
*/
// Instantiate CMS instance
$cms = new CodePressCMS($config);
@@ -219,7 +219,7 @@ $cms = new CodePressCMS($config);
* Land, IP-anonimisatie en analytics-instellingen worden bepaald op basis
* van de analytics-configuratie.
*
* @since 2.6.4
* @since 2.6.5
*/
// Analytics & GeoIP settings
$analyticsSettings = $config['analytics'] ?? [];
@@ -232,7 +232,7 @@ if (!empty($analyticsSettings['enabled'])) {
/**
* IP-anonimisatie toepassen voor opslag indien ingeschakeld.
*
* @since 2.6.4
* @since 2.6.5
*/
// Apply IP anonymization for storage if enabled
$storedIp = !empty($analyticsSettings['anonymize_ip'])
@@ -246,7 +246,7 @@ $storedIp = !empty($analyticsSettings['anonymize_ip'])
* een request-logregel, vuurt een LogManager-requestevent en registreert
* geaggregeerde analytics (mits ingeschakeld en IP niet uitgesloten).
*
* @since 2.6.4
* @since 2.6.5
*/
// Log page view (not for media/assets)
if (!str_starts_with($path, '/-media/') && !str_starts_with($path, '/-assets/')) {
@@ -291,7 +291,7 @@ if (!str_starts_with($path, '/-media/') && !str_starts_with($path, '/-assets/'))
*
* Geeft 429 bij rate-limit en 403 bij andere blokkades, met noindex-headers.
*
* @since 2.6.4
* @since 2.6.5
*/
// Block request if status is not ok
if ($requestStatus !== 'ok') {
@@ -309,6 +309,6 @@ if ($requestStatus !== 'ok') {
/**
* Pagina renderen via de CodePressCMS-instantie.
*
* @since 2.6.4
* @since 2.6.5
*/
$cms->render();