[eluser]rip_pit[/eluser]
OK, i know this post is old but i'll use it for a related question after i gave my solution to the download counter.
Here is what i use to count the number of download in my app :
Code:
Class Myclass {
/**
* docs download counter
*
* call me with : site.com/myclass/get_document/##
*
* file params are passed as url segments
* @param <str> segment(1) : myclass =controller
* @param <str> segment(2) : get_document =method
* @param <str> segment(3) : ## =doc id
* @param <str> segment(any) : /remove_error =include in url to hide any error while processing download
* @param <str> segment(any) : /remove_count =include in url to disable count for the current file
*/
function get_document() {
$this->output->enable_profiler(false);
//look for the settings in url
$current_url = current_url();
$remove_error = (bool)strrpos($current_url,'/noerror');
$remove_count = (bool)strrpos($current_url,'/nocount');
//getting doc id from url
$this->doc_id = (int)$this->uri->segment(3, 0);
//
// check doc id is ok
// -------------------------------
if( ! $this->doc_id ) {
if (!$remove_error)
log_error('error','jno file selected');
return false;
}
// LOAD MODEL AND GET FILE DATA ROW
$this->load->model('docs_model');
$f = $this->docs_model->get_by_id( $this->doc_id );
//
// found in db
if ( count($f)>0 ) {
//1 unique row returned
$doc = $f[0];
//
// create full path and read file into a string
// -------------------------------
// complete url to file
$download_url = './storage/mydocs/' . $doc->doc_filename;
$filecontent = @file_get_contents( $download_url ); // Read the file's contents, false if error
if ( $filecontent ) { //FILE READ SUCCESS
//
// COUNT ENABLED
//
if (!$remove_count) {
//
// update the number of downloads in db
// -------------------------------
$update = array(
'doc_id' => $this->doc_id,
'doc_count' => $doc->doc_count + 1 //current + 1
);
$this->docs_model->update_docs($update);
}
//
// force download and auto exit/close
// -------------------------------
$this->load->helper('download');
force_download($doc->doc_filename, $filecontent);
}
else { //ERROR READING FILE
if (!$remove_error)
log_error('error','unattended error!')
return false;
}
}//row exist
else { // doc not found in db
if (!$remove_error)
log_error('error','file not found in db!')
return false;
}
}
}//class
/*
* note: you can use config/routes.php to have a more user friendly url
* something like :
* $route['dodownload/(:any)'] = "myapp/get_document/$1";
* then when you type ".com/dodownload/##/nocount" will call ".com/myapp/get_document/##/nocount"
*/
All your download links must come by get_document() first, it count +1 every time the link is clicked (even if download is cancelled).
for this example the file are all stored in the same dir (/storage/mydocs/).
hope it can help someone.
Now, my related problem is :
how to avoid counting a unique user multiple times for the same download (or a short time redownload) ?
In short I use a Download Manager in addition to firefox that brings 2 cases with wrong counts :
case 1 :
1. click the download link
2. It counts +1 and open the Download Manager
3. when i cancel it, it auto switches to the firefox default downloader windows
4. that counts +1 again when it open the FF default downloader.
So i clicked it once but i now got 2 views
But here's the worst case :
1. click the download link and accept to download using the Download Manager
2. as it uses and opens multiple connexions to the same file, it'll bring X more views for the single click !
(as it split the download in several parralel connections, it count as many connections that were opened by the Download manager)
So I wondered if someone already met or fixed this kind of problem.
I was thinking in monitoring the user IP / time / to avoid the multiple count but i'm not sure if it could work.
Any idea ?