@texnixe Thank you for your reply.
The folder structure is organized as follows:
content
└── kunden
├── apple
│ ├── concept1
│ ├── concept2
│ └── concept3
└── sony
├── project1
└── project2
The template kunden
redirects to the home page <?php go('/') ?>
, so no content needs to be protected here yet.
I only changed the path from your cookbook:
[
'pattern' => 'kunden/(:any)/(:all)',
'action' => function ($filename) {
if (kirby()->user() &&
($page = page('kunden')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
},
],
After logging in, I can see the level of …
content
└── kunden
├── apple
… but no images are loaded here:
“Failed to load resource: the server responded with a status of 404 (Not Found).”
Access to the next level is completely denied:
content
└── kunden
├── apple
│ ├── concept1
I now have the following code (which is certainly not built efficiently), but at least makes all pages accessible and blocks direct file access. However, the code blocks the creation of thumbnails. These are displayed in their original size on the frontend.
<?php
use Kirby\Cms\Response;
Kirby::plugin('cookbook/files-firewall', [
'routes' => [
// Route for all subfolders in 'kunden', including deeper levels
[
'pattern' => 'kunden/(:all)',
'action' => function ($path) {
// Create a page based on the path
$page = page('kunden/' . $path);
// Check if the path points to a page and a user is logged in
if ($page && kirby()->user()) {
return $page;
}
// Check if the last part of the path is a file
$segments = explode('/', $path);
$filename = array_pop($segments);
$subfolder = implode('/', $segments);
if (($page = page('kunden/' . $subfolder)) &&
($file = $page->files()->findBy('filename', $filename)) &&
kirby()->user()) {
// Instead of downloading the file, send it for display in the browser
return new Response(
file_get_contents($file->root()),
$file->mime(),
200
);
}
return site()->errorPage();
},
],
],
'components' => [
'file::url' => function ($kirby, $file) {
if ($file->template() === 'protected') {
return $kirby->url() . '/' . $file->parent()->id() . '/' . $file->filename();
}
return $file->mediaUrl();
},
'file::version' => function ($kirby, $file, array $options = []) {
static $original;
// if the file is protected, return the original file
if ($file->template() === 'protected') {
return $file;
}
// if static $original is null, get the original component
if ($original === null) {
$original = $kirby->nativeComponent('file::version');
}
// and return it with the given options
return $original($kirby, $file, $options);
}
],
]);
Your solution is, of course, much more compact, but in my case I can’t get it to work.