Forum Moderators: coopster
First of all, I want to apologize if this or something similar to this has already been answered here, but since I couldn't see a search function, I don't know if that's the case (although I've been reading page-to-page the topics for an hour now... :)
So, I am building a kind of a Digital Downloads Website. For this I am using some commercial php scripts, thus I am actually a total noob on PHP, although I must say I understand the logics behind programming.
I have come to a point to restrict number of downloads per file for the (registered) user.
I want the users to be able to donwload a file only once, to prevent filesharing (e.g. the user gives his username & password to a friend, who then log in and download the same stuff for himself).
My website isn't based on the "classical" Dig.Downloads Idea ("select a file, click buy, pay, get back to the site, download file") but is rather based on a payed membership system. So, when a user pays (e.g. membership for one month) he can download everything on the website. But, he should only be able to download the same file once.
The guys on the support Forums belonging to the scripts I am using weren't really helpfull, and gave only some vague ideas on how can I do that.
This is the php File which is used to serve the download:
-----------
<?php
/*
Copyright (c)XXXX 2000-2005
*/
include_once(dirname(realpath(__FILE__)) . '/../../common/lib/resources/KT_Resources.php');
$d = 'tNG';
KT_session_start();
$uniqueId = @$_GET['id'];
if (!isset($_SESSION['tNG']['download'][$uniqueId])) {
die(KT_getResource('ERR_DOWNLOAD_FILE', $d));
}
if (!is_array($_SESSION['tNG']['download'][$uniqueId])) {
die(KT_getResource('ERR_DOWNLOAD_FILE', $d));
}
if (!isset($_SESSION['tNG']['download'][$uniqueId]['realPath']) ¦¦!isset($_SESSION['tNG']['download'][$uniqueId]['fileName'])) {
die(KT_getResource('ERR_DOWNLOAD_FILE', $d));
}
$realPath = $_SESSION['tNG']['download'][$uniqueId]['realPath'];
$fileName = $_SESSION['tNG']['download'][$uniqueId]['fileName'];
if (md5($realPath)!= $uniqueId) {
die(KT_getResource('ERR_DOWNLOAD_FILE_WRONG_HASH', $d));
}
if (!@fopen($realPath, "rb")) {
die(KT_getResource('ERR_DOWNLOAD_FILE_NO_READ', $d, array($realPath)));
}
//define('MAX_READ',131072);
$mime_type = (function_exists('mime_content_type'))? mime_content_type($realPath): 'application/octet-stream';
header('Content-type: '.$mime_type);
header('Cache-control: private');
header('Content-Length: ' . filesize($realPath));
header('Content-disposition: attachment; filename="' . $fileName . '";');
if (!readfile($realPath)) {
header('Status-code: 404');
die(KT_getResource('ERR_DOWNLOAD_FILE_NO_READ', $d, array($realPath)));
}
exit;
?>
--------
As you see it's based on session id. Now I know I should have an extra table (let's call it 'download_tracker') where I will put user_id and file_id and where the records should be updated when a user downloads a file.
Then I need a function in the script above to check this:
User clicks on "download now", the script checks in the 'download_tracker' whether he already downloaded that file before;
if not, the record is updated in the table and he gets the file;
if he did download the file before; he gets redirected to a page ('sorry.php') with a "sorry fella you already downloaded this" text.
PLEASE, can you guys just put the necessary code for doing this in the right place on my script and highlight it?
I really, really would appreciate your help.
I think from a learning perspective, you should try this yourself. You seem to have a grasp of what you want, so why not give it a try? I doubt too many people here will have time to write the script for you, we are here to offer help and advice only.
Give it a go and if you have problems, come back and let us know and we will try and help you out.
Good luck.
dc
------------
$query = sprintf('INSERT INTO download_tracker(id_usr, title, date) VALUES(%d, "%s", NOW())', $_SESSION['kt_user_id'], $fileName);
mysql_query($query, $connCMS) or die(mysql_error());
------------
I would put this just before the exit statement. I know that this is the way to "track" the downloads, but that is not my real problem.
The Problem is how to tell the script to check IF a user has already downloaded a file? I don't know PHP, so I don't know how to construct this. But I do now it would be something like this:
I would probably have to put this code BEFORE the code above:
if (some variable) is TRUE (if the file id/name is already in the dt table)
redirect to "sorry.php"
(else, or no else, i don't know) continue with that code above (which means the user gets his file and the record is updated in the table).
You see, I actually know how am I supposed to construct this, but I really don't know how to use the commands (if, else, do, ...)
As a matter of fact, I am right now reading a book about PHP, but my problem is: I have to finish this script in 2 days :(
Of course, I would like to learn PHP, but you should also understand that I am a father of 3 little kids, have a lot to do, and don't have much time to search, read & learn like I once had... :(
SELECT COUNT(*) FROM download_tracker WHERE user_id = {$_SESSION['KT_user_id']} && file = $filename}
So, I have to check if the count is zero, then continue with the code for Inserting into table and downloading, or if the count is greater than zero to display the "sorry.php" page.
This must all sound so simple to you guys, but I have no idea how to do it. How do I "check" it? I can't just write "if count==0 Insert ...", can I?
The code you have shown will count the number of rows or entries in a database table, which you don`t want. What you want to do is update the count and see if any rows were affected with the query. If there were, then ok, if not, then not ok.
Something like:
mysql_query("UPDATE download_tracker SET count = '1' WHERE user_id = '".$_SESSION['KT_user_id']."' AND file = '$filename' AND count = '0' LIMIT 1") or die(mysql_error());
Where count is a field in your database along with the file name and user id.
Then:
if (mysql_affected_rows()>0)
{
//ok, download file
}
else
{
//not ok
}
mysql_affected_rows() returns how many rows were affected by the last mysql query. So, if the count is already 1, then 0 rows will be updated.
Hope that makes sense. You can do it other ways, but that should be ok.
dc
just wanted to ask you if this statement of yours is ok:
if (mysql_affected_rows()>0)
{
//ok, download file
}
else
{
//not ok
}
Doesn't this mean "if the count is greater than zero then download the file"?
But I need the opposite: "if the count is greater than zero DONT allow downloading"
The previous statement updates the download count from 0 to 1. If the count is already 1, then mysql_affected_rows will return 0 because nothing will get updated.
So, what the if statement it saying is:
if (count was 0 and has been updated to 1, thats ok)
{
}
else (count was already 1, so nothing got updated, which means the file has already been downloaded)
{
}
Hope that makes sense. For more info see the following:
[hk2.php.net...]
dc
I experimented a bit and noticed that, if using this exactly the way you wrote it, nothing happens in the download_tracker table. No records are inserted/updated.
Now, I thought I could use this:
If we suppose that the User didn't download the file before, he gets the download and the record is inserted into table with the insert statement:
$query="INSERT INTO download_tracker(user_id,file,count)VALUES('$tmp_user_id','$tmp_file_id','1')";
mysql_query ($query) or die ("couldnt add data");
Now, BEFORE this code, I need to use the code which checks the download_table, and the field count. How is this done? With the SELECT statement?
I used this:
$check="SELECT * FROM download_tracker WHERE user_id ='$tmp_user_id' AND file = '$tmp_file_id' AND count >= 0";
mysql_query ($check) or die ("couldnt check data");
Then how would the "if" statement look like? I would need something that checks "if the field 'count' is >0 then redirect to 'sorry.php'
else -> the Code above with the Insert record.
At the end the code should look like this:
$check="SELECT * FROM download_tracker WHERE user_id ='$tmp_user_id' AND file = '$tmp_file_id' AND count >= 0";
mysql_query ($check) or die ("couldnt check data");
if (?>0)
{
redirect to sorry.php
}
else
{
$query="INSERT INTO download_tracker(user_id,file,count)VALUES('$tmp_user_id','$tmp_file_id','1')";
mysql_query ($query) or die ("couldnt add data");
I don't know what to put at the "if" statement. And since I didn't know what to write for the 'count' field I wrote >=0
And of course I get a bunch of errors with this, because the if statement isnt correct, i know that, but don't know what to put there.
-------------
I just tried one more time your solution (wanted to be sure I didnt make a mistake before). I used the following code:
--------------
mysql_query("UPDATE download_tracker SET count = '1' WHERE user_id = '$tmp_user_id' AND file = '$tmp_file_id' AND count = '0' LIMIT 1") or die(mysql_error());
if (mysql_affected_rows()>0)
{
//define('MAX_READ',131072);
$mime_type = (function_exists('mime_content_type'))? mime_content_type($realPath): 'application/octet-stream';
header('Content-type: '.$mime_type);
header('Cache-control: private');
header('Content-Length: ' . filesize($realPath));
header('Content-disposition: attachment; filename="' . $fileName . '";');
if (!readfile($realPath)) {
header('Status-code: 404');
die(KT_getResource('ERR_DOWNLOAD_FILE_NO_READ', $d, array($realPath)));
}
}
else
{
echo "Jukeni shkarkuar kete media njehere. Ju lutemi zgjedhni nje media tjeter";
}
exit;
?>
---------
When I use this, I get the "sorry" text for EVERY file I try to download, and the download_tracker (as i said before) doesn't get updated (nothing gets inserted).
With your help and a little help from a PHP book, I made it work.
I used the following code:
$check="SELECT count FROM download_tracker WHERE user_id ='$tmp_user_id' AND file = '$tmp_file_id'";
$result=mysql_query($check) or die ("couldnt execute query");
$row = mysql_fetch_array($result,MYSQL_ASSOC);
if ($row['count']>0)
{
echo "Ju e keni shkarkuar kete media njehere. Zgjedhni nje media tjeter.";
}
else
{
$query="INSERT INTO download_tracker(user_id,file,count)VALUES('$tmp_user_id','$tmp_file_id','1')";
mysql_query ($query) or die ("couldnt add data");
//define('MAX_READ',131072);
$mime_type = (function_exists('mime_content_type'))? mime_content_type($realPath): 'application/octet-stream';
header('Content-type: '.$mime_type);
header('Cache-control: private');
header('Content-Length: ' . filesize($realPath));
header('Content-disposition: attachment; filename="' . $fileName . '";');
if (!readfile($realPath)) {
header('Status-code: 404');
die(KT_getResource('ERR_DOWNLOAD_FILE_NO_READ', $d, array($realPath)));
}
}
exit;
?>