Download Code Redemption System

Created by Phil Thompson

I recently seen a post on the css-tricks.com forum where a guy was asking how to build a system to he can issue a download code to restrict access to a download to a certain person for a restricted amount of time.

This isn’t a very difficult system to build but it could be hard to get your head around. To lay it out what we are going to want the code to do is the following:

  1. Generate and store a code for a client.
  2. Add a time stamp to the code so we can restrict access.
  3. Get the code out of the address bar so we can check if it exists as well as the file name.
  4. Check if the client is in time to claim the download.
  5. Give the client the download whilst hiding the location of the file.

So lets work our way through the list.

1. Generate and store a code for a client.

Right this section you are really going to need to have two main things in place your mySQL table and the php file to create it (This normally I would put in a php function), this time I’m going to call it create.php.

The table for the mySQL I’m going to call it codes have just two columns one called code and one called time. The code column I will make a varchar with a 48 character limit and the time column I will make an int with a 20 character limit. Now that is done we can move onto the php.

What I am going to do is pretend that their is another page that will have the clients name, email address and the file name submitted via a form using the post action to our file/function.

So the first thing we will have out file do is grab all of that data it is getting sent plus we are going to grab the current unix timestamp time.


  <?php
    // This will get the name.
    $name = $_POST['name'];

    // This will get the clients email
    $email = $_POST['email'];

    // This will get the file name
    $file = $_POST['file'];

    // This will get the current unix timestamp
    $time = time();
  ?>

Now the way I am going to generate a unique code is add the clients name, the file name and the timestamp into one string then after that I will use the md5() function to convert that into a code.


  <?php
    // This combines all the data together in one string.
    $combine = $name . $file . $time;

    // This turns it into a code using the md5() function.
    $code = md5($combine);
  ?>

Now we have all that set up their is just two things we need to do with that stuff, one is send out the code or just display it for the client and two place the code and timestamp in the database, so lets send out the link to the client so they can get hold of the file.


  <?php
    $to = $email;
    $from = 'From: Your site name <[email protected]>';
    $subject = 'Redeam Code';
    $message = 'This is your download code for your item';
    $message += '<a href="http://www.yourdomain.com/download.php?file=' .$file. '&code=' .$code. '">http://www.yourdomain.com/download.php?file=' .$file. '&code=' .$code. '</a>';

    mail($to, $subject, $message, $from);
  ?>

and now we have one last thing to do in this section and that is too add the code into the mySQL database which I will mix into the next section.

2. Add a timestamp to the code to restrict access.

In this version I am going to give the client 24hrs to download the file. Now because we are using the timestamp we have to work in seconds so 24hrs x 60min x 60secs = 86400 seconds. This means we will have to take the timestamp that we have stored and add 86400 to it.


  <?php
    $timeLimit = 86400; // 24 hrs in seconds
    $expTime = $time + $timeLimit;
  ?>

and then finally all we need to do is upload the code and the expiration time to the database.


  <?php
    $db_host = 'http://localhost';
    $db_user = 'root';
    $db_pass = 'password';
    $db_name = 'database_name';

    mysql_connect($db_host, $db_user, $db_pass) or die('Could not connect to the database');

    mysql_select_db($db_name) or die('Could not select the table.');

    $query = "INSERT INTO `codes` (code, time) VALUES ('$code', '$expTime')";

    mysql_query($query);
  ?>

That is us done with the first file and now we can move on to how to check the code and issue the download.

3. Get the code out of the address bar so we can check if it exists as well as the file name.

The link we have given to the client is sending them to a file called download.php so lets make the file that checks the code be called download.php.

The very first thing we are going to need to do in this file is get the data out of the address bar as well as the current unix timestamp time. We do this using the following code.


  <?php
    // This stores the file name
    $filename = $_GET['file'];

    // This stores the code
    $code = $_GET['code'];

    // This gets and stores the current timestamp time.
    $time = time();

    // This will come into play later
    $download = false;
  ?>

Then we need to connect to the database to see if this code does exist. So the following code will connect to the database and search for a matching code and report back what it finds.


  <?php
    $db_host = 'http://localhost';
    $db_user = 'root';
    $db_pass = 'password';
    $db_name = 'database_name';

    mysql_connect($db_host, $db_user, $db_pass) or die('Could not connect to the database');

    mysql_select_db($db_name) or die('Could not select the table.');

    $query = "SELECT * FROM `codes` WHERE `code` = '$code'";

    $result = mysql_query($query);

    if ($row = mysql_fetch_assoc($result)) {

      // The code is in the database.

  } else {

    // Code doesn't exist
    echo 'Sorry your download code could not be found.';

}
  ?>

4. Check if the client is in time to claim the download.

To check if the client is in time to claim their download is a very simple task. We are going to add a couple of lines to the previous code to get hold of the expiration time and compare it with the current time.


  <?php
    $db_host = 'http://localhost';
    $db_user = 'root';
    $db_pass = 'password';
    $db_name = 'database_name';

    mysql_connect($db_host, $db_user, $db_pass) or die('Could not connect to the database');

    mysql_select_db($db_name) or die('Could not select the table.');

    $query = "SELECT * FROM `codes` WHERE `code` = '$code'";

    $result = mysql_query($query);

    if ($row = mysql_fetch_assoc($result)) {

      // The code is in the database.

      // Get the expiration time.
      $expTime = $row['time'];

      // Now to see if the client is in time to claim their download.
      if ($time < $expTime) {
        // The client is in time.
        $download = true;

    } else {
        // The client is out of time.
        $download = false;
        echo 'Sorry time limit has expired.'; 
    }

  } else {

    // Code doesn't exist
    echo 'Sorry your download code could not be found.';

}
  ?>

5. Give the client the download whilst hiding the location of the file.

Finally we are on the home stretch now and all we have to do is now issue the download whilst hiding the true location of the file.

First lets use that $download that we set earlier to see if we can start the download to the client.


  <?php
    if ($download) {
    // Start the download.
    }
  ?>

and now we can issue the download and hide the location of the file.


  <?php
    if ($download) {
      // Start the download.
      $file = "path/to/download/".$filename;
      $fp = fopen($file, 'rb');

      header("Content-Type: application/octet-stream");
      header("Content-Disposition: attachment; filename=$filename");
      header("Content-Length: " . filesize($file));
      fpassthru($fp);
    }
  ?>

Fin

There we go that is the files complete and you should now be able to restrict all of your downloadable files.

Download the files here

If you have any problems with setting this up then let me know either by comment or send me a message via the contact page.

comments powered by Disqus