I had something (kind of) similar with one client. They wanted visitors to fill in a form with some info before downloading some files which could be on any page.
Basically what I did is create a folder under AssetAdmin called FilteredDownload
and any place in that folder will go through the filtering (form etc...)
I had this rule in the .htaccess
(which could be edited...) redirecting any request to any of those file to a Downloader_Controller
RewriteCond %{REQUEST_URI} /assets/FilteredDownload [NC]
RewriteCond %{REQUEST_URI} !/assets_temp [NC]
RewriteCond %{REQUEST_FILENAME} \.(pdf|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$ [NC]
RewriteRule .* downloader?file=%{REQUEST_FILENAME}&%{QUERY_STRING} [L,NC]
Then I just used that controller to server the form and the files.
In your case you could just use that Controller to test if the visitor is logged in and if not redirect him/her to the login page, deny access or whatever...
Not exactly the same as your problem but I could easily see this adapted?
EDIT
Had a better look at it and based on the above, this seems to work:
SilverStripe 3+
Adding this to .htaccess
:
RewriteCond %{REQUEST_URI} /assets/MembersOnly [NC]
RewriteCond %{REQUEST_FILENAME} \.(pdf|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$ [NC]
RewriteRule .* filedownloadpermission?file=%{REQUEST_FILENAME}&%{QUERY_STRING} [L,NC]
So every files uploaded under /assets/MembersOnly
will first have their request passed through /filedownloadpermission
before download.
Define the Director
rule in config.yml
:
---
Name: myroutes
After: framework/routes#coreroutes
---
Director:
rules:
'filedownloadpermission/$Action/$ID/$Name': 'FileDownloadPermission_controller'
Then our controller FileDownloadPermission_controller.php
that will check for permissions before serving the file or not:
<?php
class FileDownloadPermission_controller extends ContentController
{
private static $allowed_actions = array (
);
public function init() {
parent::init();
if( !$member = Member::currentUser() )
{
Security::permissionFailure();
}
}
public function index()
{
$file = $this->request->getVar('file');
$fileAssetPath = substr($file, stripos($file, 'assets'));
$fileObj = File::get()->filter(array('Filename' => $fileAssetPath))->first();
if ( $fileObj )
{
$data = file_get_contents( $fileObj->getFullPath() );
$name = $fileObj->getFilename();
$response = SS_HTTPRequest::send_file($data, $name);
return $response;
}
else {
//Return 404 or whatever...
}
}
}
This is actually written for SilverStripe 3.1 but can easily be adapted for 2.4:
$allowed_actions
should be public
Director
rule to be added to _config.php
instead
- Update
File::get()...
to DataObject::get...
So this give us for SilverStripe 2.4+
in _config.php
Director::AddRules(100, array('filedownloadpermission/$Action/$ID/$OtherID' => 'FileDownloadPermission_controller'));
and our controller FileDownloadPermission_controller.php
:
<?php
class FileDownloadPermission_controller extends ContentController
{
static $allowed_actions = array (
);
public function init() {
parent::init();
if( !$member = Member::currentUser() )
{
Security::permissionFailure();
}
}
public function index()
{
$file = $this->request->getVar('file');
$fileAssetPath = substr($file, stripos($file, 'assets'));
$fileObj = DataObject::get(
"File",
"Filename = '".$fileAssetPath."'",
null, null, "1");
if ( $fileObj )
{
$fileObj = $fileObj->shift();
$data = file_get_contents( $fileObj->getFullPath() );
$name = $fileObj->getFilename();
$response = SS_HTTPRequest::send_file($data, $name);
return $response;
}
else {
//Return 404 or whatever...
}
}
}
This is quite a quick solution and can probably be a bit better but should give you a good start_