Fix: _ mappen verborgen in frontend + image URL rewriting naar /-media/

- Bug: mappen met _ prefix (zoals _drafts, _data) werden zichtbaar in
  frontend navigatie omdat scanDirectory() alleen . en - oversloeg.
  scanDirectory(), searchInDirectory() en scanForPageTitles() skippen
  nu ook _ prefix (consistente filtering).
- Bug: images in markdown niet weergegeven. ![alt](test.svg) werd
  <img src=test.svg> (relatief -> 404) en ![alt](/content/test.svg)
  werd /content/test.svg (buiten webroot -> 404). processContent()
  herschrijft nu lokale image/link URLs naar /-media/ endpoint.
  Externe URLs (http(s)://), /-media/, /-assets/, /themes/, /plugins/,
  /admin/, data: en mailto: worden ongewijzigd gelaten.
- Release notes v2.6.2 bijgewerkt met beide bugfixes
- Pentest 30/30, WCAG 25/25
This commit is contained in:
2026-08-19 10:52:07 +00:00
parent 7249aca885
commit e926a3a40d
3 changed files with 44 additions and 5 deletions
+38 -4
View File
@@ -330,7 +330,8 @@ class CodePressCMS {
$result = [];
foreach ($items as $item) {
if ($item[0] === '.' || $item[0] === '-') continue;
// Skip hidden/system entries: dotfiles, -assets, _drafts, etc.
if ($item[0] === '.' || $item[0] === '-' || $item[0] === '_') continue;
// Skip assets directory (old name, kept for safety)
if ($item === 'assets' && is_dir($dir . '/' . $item)) continue;
@@ -397,7 +398,8 @@ class CodePressCMS {
$items = scandir($dir);
foreach ($items as $item) {
if ($item[0] === '.') continue;
// Skip hidden/system entries (consistent met scanDirectory)
if ($item[0] === '.' || $item[0] === '-' || $item[0] === '_') continue;
$path = $dir . '/' . $item;
$relativePath = $prefix ? $prefix . '/' . $item : $item;
@@ -886,7 +888,8 @@ class CodePressCMS {
sort($items);
foreach ($items as $item) {
if ($item[0] === '.') continue;
// Skip hidden/system entries (consistent met scanDirectory)
if ($item[0] === '.' || $item[0] === '-' || $item[0] === '_') continue;
$path = $dir . '/' . $item;
$relativePath = $prefix ? $prefix . '/' . $item : $item;
@@ -1802,6 +1805,37 @@ class CodePressCMS {
private function processContent(string $content): string
{
return str_replace('-/assets/', '/-assets/', $content);
// Legacy rewrite for the old -/assets/ shortcut
$content = str_replace('-/assets/', '/-assets/', $content);
// Rewrite <img src="..."> and <a href="..."> that point to files in the
// content directory so they are served via the /-media/ endpoint. The
// content/ directory lives outside the webroot, so raw URLs like
// "test.svg", "/content/test.svg" or "sub/test.svg" would otherwise 404.
//
// Skipped (left untouched):
// - absolute URLs (http://, https://, //)
// - already rewritten /-media/ and /-assets/ URLs
// - theme/plugin asset URLs (/themes/..., /plugins/..., /admin/...)
// - data: and mailto: URLs
// - fragment-only URLs (#anchor)
$content = preg_replace_callback(
'~(<(?:img|a)\b[^>]*\b(?:src|href)\s*=\s*")([^"]+)(")~i',
function ($m) {
$url = $m[2];
// Leave absolute, already-rewritten, asset, data: and anchor URLs alone
if (preg_match('~^(?:[a-z][a-z0-9+.\-]*:|//|/themes/|/plugins/|/admin/|/-media/|/-assets/|data:|mailto:)~i', $url)) {
return $m[0];
}
// Strip a leading /content/ prefix if present, then prefix with /-media/
$clean = preg_replace('~^/content/~', '', $url);
// Strip a leading slash so it becomes a clean /-media/<path>
$clean = ltrim($clean, '/');
return $m[1] . '/-media/' . $clean . $m[3];
},
$content
);
return $content;
}
}