Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to track (direct) file downloads

what is the best method to track direct file downloads? I found some solution, for example this one:

http://www.gayadesign.com/diy/download-counter-in-php-using-htaccess/

But it is not working for me, I only get a blank page when I am trying to download a file + I don't know it is enough secure or not...

Google Analytics only works with javascript, can't track direct file downloads.

Best would be a secure and own hosted solution.

like image 463
Adrian Avatar asked Nov 16 '11 17:11

Adrian


People also ask

How can I track the number of downloads?

To view file downloads, log in to your Google Analytics account and select the website where you'd like to track file downloads. If you've enabled downloads tracking as page views, you can find out the downloads report in the All Pages report along with other blog posts and pages.

Can I see how many people downloaded my file?

Click “My Drive,” located on the left-hand side. Select the info icon (a gray circle with a white, lower case “i” in the middle) in the top-right corner. Hit “Activity” to access any recent changes. To get more specific, you can select the file or folder to see the activity specifics.

Can you track PDF downloads?

To enable download tracking, you might want to use a plugin like MonsterInsights. Once the plugin is installed, PDF downloads will be tracked as events in your Google Analytics dashboard. The good news with some of these plugins is that you don't need to do any more work than download and install it.

Can Google track downloads?

You can set Google Analytics up to track downloads automatically. Depending on your website's setup and your resources, there are a number of options for tracking file downloads.


2 Answers

Feel free to use :)

.htaccess:

RewriteEngine on    
RewriteRule ^(.*).(rar|zip|pdf)$ http://xy.com/downloads/download.php?file=$1.$2 [R,L]    

mysql:

CREATE TABLE `download` (
    `filename` varchar(255) NOT NULL,
    `stats` int(11) NOT NULL,
    PRIMARY KEY  (`filename`)
)

download.php

<?php

mysql_connect("localhost", "name", "password")
or die ("Sorry, can't connect to database.");
mysql_select_db("dbname"); 
$baseDir = "/home/public_html/downloads"; 
$path = realpath($baseDir . "/" . basename($_GET['file'])); 

if (dirname($path) == $baseDir) {
if(!is_bot())
mysql_query("INSERT INTO download SET filename='".mysql_real_escape_string(basename($_GET['file']))."' ON DUPLICATE KEY UPDATE stats=stats+1");


header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . basename($_GET['file']));
header("Content-Length: ".filesize($path));
header("Content-Type: application/force-download");
header("Content-Transfer-Encoding: binary");
ob_clean();
ob_end_flush();
readfile($path);    
}

function is_bot()
{

    $botlist = array("Teoma", "alexa", "froogle", "Gigabot", "inktomi",
    "looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory",
    "Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot",
    "crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp",
    "msnbot", "appie", "FAST", "WebBug", "Spade", "ZyBorg", "rabaz",
    "Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot",
    "Mediapartners-Google", "Sogou web spider", "WebAlta Crawler","TweetmemeBot",
    "Butterfly","Twitturls","Me.dium","Twiceler");

    foreach($botlist as $bot)
    {
        if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false)
        return true;    // Is a bot
    }

    return false;
}

?>

Source - gayadesign.com

like image 131
Adrian Avatar answered Sep 24 '22 17:09

Adrian


Your apache logs should contain a lot of info, but I think what you're asking for is more control over what gets logged and when. So what you want to do is have two pages: one with the link to the file, and the other that tracks the file, like so:

file_page.php

<a href="download.php?id=1234">Download File!</a>

download.php

<? // Code to track the file using PHP, whether that means storing data in a database, saving to a log, or emailing you. I'd use a DB, like so:

   // Prep the vars
   $file_id = $_GET['file_id']; // You should sanitize this first.
   $file_path = '/files/'.$file_id.'.pdf';

   // Save data to database
   mysql_query('INSERT INTO download_log
      SET file_id = '.$file_id.',
          date_downloaded = '.date('Y-m-d H:i:s').',
          user_id = '.$_SESSION['user_id']);

   // Now find the file and download it
   header('Content-type: application/pdf');
   header('Content-Disposition: attachment; filename='.$file_id.'.pdf); // or whatever the file name is
   readfile($file_path);

Something like that, anyway.

The page will be blank when it is done, but all browsers should begin downloading the file when the page is loaded.

So what I'm doing here is I'm saving the file ID, the current datetime, and the user ID of the person downloading it (from a $_SESSION variable). You probably want to store a lot more information, such as the user's IP address, the HTTP_REFERRER or other $_SERVER information, so you can track where the user came from and when and what they downloaded.

Good luck.

like image 33
Jemaclus Avatar answered Sep 23 '22 17:09

Jemaclus