Hello,
I am not a ScriptCase expert, but developer. And as @aducom say, maintenance is really difficult for large files. In other hand, databases like SQL Server manages/serves tiny files very well when they are stored at database layer even faster than filesystem. So, whatever be the case, you can do the following (I will give you and example of a architecture).
1. Do not store file in mysql, but filename. In the database you could save the relations between files are user, referring just the filename, take a look to the table:
uploads_table
id_store | filename | mime_type | user | status
1 | foo.jpg | image/jpeg | 1 | in_revision
2 | bar.pdf | application/pdf | 2 | accepted
See how the user 1 only has access to foo.jpg file, and user 2 only have access to bar.pdf file.
2. Restriction for download. Some people is evil, and share the link for resources like example.com/files/bar.pdf, I mean, the direct path to the file. This is wrong, and there is not way control who can access the file or not. So, the trick here is to make you own download manager calling a script instead a file. How can I do that? A blank application could be the answer, so the idea is download links like this: example.com/download?name=bar.pdf or example.com/download?name=foo.jpg
// step 1, read the session to know who is accesing this file
$userGroup = $_SESSION['USER_GROUP'];
$userID= $_SESSION['USER_ID'];
// step 2, is this guy and administrator?
if ($userGroup === 'administrator'){
// no restriction, give him the resources, which is the name of the file?
$filename = $_GET['name'];
$path = $this->Ini->path_docs . $filename;
$mimeType = execute_query("select mime_type from uploads_table where name = '{$name}' ");
buildDownload($path, $mimeType);
}
else{
// if this guy is not admin, then check if he has the perfmission to file
$row = execute_query("select * from uploads_table where name = '{$name}' and user = {$userID}");
if ($row != null){
// cool! he has permission
$filename = $_GET['name'];
$path = $this->Ini->path_docs . $filename;
$mimeType = $row['mime_type'];
buildDownload($path, $mimeType);
}
else{
echo "sorry, this file is not available";
}
}
function buildDownload($path, $mimeType){
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: '. $mimeType . '');
header('Content-Disposition: attachment; filename="'. basename($path ) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($path ));
readfile($path );
exit;
}
3. Administrators: Administrator can see every single uploaded file, so you can easily make a grid selecting the records from uploads_table. The magic here is to make a new extra field called “Download” where you can build a grid column allowing the administrator to download the resource and review it, for example, at onRecord() event you can do:
// link to blank application with file requested
{download} = "<a href='download?name=[filename]'>[filename]</a>";
4. Logged users and visitors. Take this case, a user has accepted file and then he share the link example.com/download?name=foo.jpg to his friend. The system will try to read the session of that visitor, when the sql query is executed never get a row, because there is not id session corresponding to the requested file. Between logged users happens the same, the ID read from session do not match with the file associated at the db record.
This is a basic model of resources permissions, with a cool corrections could be very robust link caring from evil people. Take in consideration that:
- The code is pseudo-code, it is just giving you the path to follow
- Never use that code in production, should be validated before
- I am calling functions that do not exist, it is just an example of similar functions that could called at that point.
Advantages:
- Files easy to migrate. If you change your server, just move your doc’s directory
- Easy to improve functionalities. If eventually you need to track downloaded files, count downloads per file, etc; just inject code into Download application to fit your needs.