By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,267 Members | 1,808 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,267 IT Pros & Developers. It's quick & easy.

HELP! Trying to add Email Notification to Download File Code

P: n/a
I have used some free code for listing files for download, but I want to
send an email to the administrator when the file has been downloaded. I
have got some code in here that does it, but it will not print in the
username or email amddress of the person doing the download - which I am
collecting from a form on the previous page. I can get the name and
email address to print out normally, just not into the email sending
body. I have attached code below:

<?php
//## snip
//### http://www.tbmnet.de/tbmnet.php?content=php_downloader
//### Copyright (c) 2004 Till Biedermann <ti************@yahoo.de> ####

//################################################## ##############################
//### ####
//### CONFIGURATION - edit these variables for your needs. ####
//### ####
//### !!! pay attention to the syntax !!! ####
//### ####
//################################################## ##############################

// main configuration------------------------------------

$standalone = "true";

$custom_script_name = "downloader.php";

$enable_stats = "true";

$download_stats_file = "./download_stats";

$download_folder = "./downloads/";

$auto_create_filelist = "true";

$email_notify = 1; // Would you like to get get an email when
someone downloads file? 1 = yes 0 = no

$admin_email = "webmaster@-.com.au"; // if so enter email address here

// define download filelist when auto_create_filelist is set to
"false"-----------------

$download_filelist = array( "name1" =array( "file1.zip",
"application/octet-stream",
"description1"),
"name2" =array( "subfolder1/file2.zip",
"application/octet-stream",
"description2"),
"name3" =array( "subfolder2/file1.zip",
"application/octet-stream",
"description3"));

// standalone modus configuration--------------------------

$headline_string = "List of avalible downloads";

$css_code = <<<CSS_CODE

/* here you can edit the css code */

body { font-family: Tahoma, sans-serif; }
img { border: 0px;
margin-top: 6px; }
h2 { margin-bottom: 30px;
background-color: #eeeeee;
color: #c0c0c0;
letter-spacing: .2em;
padding: .2em;
text-align: center;
border-top: solid #aaaaaa 1px;
border-bottom: solid #aaaaaa 1px; }
table { border-collapse: collapse;
width: 80%;
margin-left: auto;
margin-right: auto;
margin-bottom: 10px;
border: solid #dddddd 1px; }
th { background-color: #dddddd; }
td { padding: 8px 10px 8px 10px;
background-color: #ffffff;
border: solid #dddddd 1px; }
a { text-decoration: none;
font-weight: bold; }

/* css code editing ends here */

CSS_CODE;
// !!! dont't change the position of the operator CSS_CODE and don't
write anything behind, it must be alone at the beginning of the line

//################################################## ##############################
//### ####
//### CONFIGURATION - ends here ####
//### ####
//### !!! don't edit anything above, except you know what you are
doing !!! ####
//### ####
//################################################## ##############################

$download = $_GET["download"];
$SCRIPT_NAME = getenv("SCRIPT_NAME");
$usrname = $_POST["usrname"];
$usremail = $_POST["usremail"];


// initialize global
variables-----------------------------------------------------------

$GLOBALS["SCRIPT_NAME"] = getenv("SCRIPT_NAME");
$GLOBALS["enable_stats"] = $enable_stats;
$GLOBALS["download_stats_file"] = $download_stats_file;
$GLOBALS["download_folder"] = $download_folder;
$GLOBALS["auto_create_filelist"] = $auto_create_filelist;
$GLOBALS["download_filelist"] = $download_filelist;
$GLOBALS["download"] = $download;
$GLOBALS["usrname"] = $usrname;
$GLOBALS["usremail"] = $usremail;


// auto create download filelist----------------------------

if ($auto_create_filelist=="true") {
unset($download_filelist);
$current_dir=getcwd();
chdir($download_folder);
$directory=dir("./");
while ($file = $directory->read()) {
if (is_file($file) and $file!=basename($SCRIPT_NAME) and
$file!=basename($download_stats_file) and $file!=$custom_script_name) {
$download_filelist[$file][0]=$file;
$download_filelist[$file][1]="application/octet-stream";
}
}
$directory->close();
chdir($current_dir);
}

// download handling----------------------------
if (isset($download)) {
if (isset($download_filelist[$download])) {
$filename=$download_folder.$download_filelist[$download][0];
if (file_exists($filename)) {
if ($enable_stats=="true")
{
if (file_exists($download_stats_file) and
is_writable($download_stats_file)) {
foreach (file($download_stats_file) as $line)
{
$array=explode("|",$line);
$download_stats_file_array[$array[0]]=$array[1];
}
$download_stats_file_array[$download]++;
$handle=fopen($download_stats_file,"w");
foreach ($download_stats_file_array as $value) {
fputs($handle,key($download_stats_file_array)."|". $value."|\n");
next($download_stats_file_array);
}
fclose($handle);
email_admin($usrname, $usremail);
}
else { die("Sorry, no downloads avalible."); }
}

header("Content-Type: ".$download_filelist[$download][1]);
header("Content-Disposition: attachment;
filename=\"".basename($filename)."\"");
readfile($filename);
exit;
}
else { die("Sorry, but the requested file could not be found."); }
}
else { die("Sorry, but the requested download does not exist."); }
}

// functions---------------------------

function manage_download_stats()
{
$download_stats_file = $GLOBALS["download_stats_file"];
$download_filelist = $GLOBALS["download_filelist"];

// create download stats file if missing--------------
if (!file_exists($download_stats_file)) {
$handle=fopen($download_stats_file,"w");
foreach($download_filelist as $array) {
fputs($handle,key($download_filelist)."|0|\n");
next($download_filelist);
}
fclose($handle);
}
// read download stats file----------------------
foreach (file($download_stats_file) as $line) {
$array=explode("|",$line);
$download_stats_file_array[$array[0]]=$array[1];
}

return $download_stats_file_array;
}

function print_download_table()
{
$enable_stats = $GLOBALS["enable_stats"];
$download_folder = $GLOBALS["download_folder"];
$auto_create_filelist = $GLOBALS["auto_create_filelist"];
$download_filelist = $GLOBALS["download_filelist"];
$SCRIPT_NAME = $GLOBALS["SCRIPT_NAME"];
$usrname = $GLOBALS["usrname"];
$usremail = $GLOBALS["usremail"];

// get download stats---------------------------
if ($enable_stats=="true") {
$download_stats_file_array=manage_download_stats() ; }
// create download table from download file list-------
echo "<table><tr><th>file</th>";
if ($auto_create_filelist!="true") { echo "<th>description</th>"; }
echo "<th>filesize</th>";
if ($enable_stats=="true") { echo "<th>downloads</th>"; }
echo "</tr>";
foreach($download_filelist as $download_filelist_array) {
if (!isset($download_stats_file_array[key($download_filelist)])) {
$download_stats_file_array[key($download_filelist)]=0; };
echo "<tr><td><a href
=\"$SCRIPT_NAME?download=".urlencode(key($download _filelist))."\"
title=\"click to download\">".key($download_filelist)."</a></td>";
if ($auto_create_filelist!="true") { echo
"<td>$download_filelist_array[2]</td>"; }
echo
"<td>".sprintf("%.1f",@filesize($download_folder.$ download_filelist_array[0])/1024)."K</td>";
if ($enable_stats=="true") { echo
"<td>".$download_stats_file_array[key($download_filelist)]."</td>"; }
echo "</tr>";
next($download_filelist);
}
echo "</table>";
}


function email_admin($usrname, $usremail)
{
$usrname = $GLOBALS["usrname"];
$usremail = $GLOBALS["usremail"];
$download = $GLOBALS["download"];
global $admin_email, $email_notify, $HTTP_USER_AGENT, $REMOTE_ADDR,
$HTTP_REFERER, $strname, $stremail;
// email admin if it's enabled
if($email_notify) {

if($final_result != "7") {

// get the downloader's info

$date = date("Y-m-d H:i:s");
$ip = $REMOTE_ADDR;
$browser_info = $HTTP_USER_AGENT;
$host = gethostbyaddr($ip);
$referer = $HTTP_REFERER;
$strname = $name;
$stremail = $email;

// Email body text info
$from_info = "The following file has been downloaded:

File: $download

User Details
================
Name: $usrname
Email: $usremail

IP: $ip
HOST: $host
Browser: $browser_info
Time: $date

Referred by: $referer

";
$subject = "File Downloaded: $download";

// echo "in footer, trying to send mail: $admin_email, $final_result,
$from_info, $subject";

mail($admin_email, $subject, $from_info, "From: downloads@--.com.au");
} // end of if final result is not empty
} // end of if
}



// standalone output----------------------------------

if ($standalone=="true") {
// header-----------------------------------------------
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"
\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">";
echo "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" >";
echo "<head><meta http-equiv=\"Content-Type\" content=\"text/html;
charset=iso-8859-1\" />";
echo "<meta name=\"author\" content=\"Till Biedermann\" />";
echo "<meta name=\"description\" content=\"download system\" />";
echo "<title>Downloads</title>";
echo "<style type=\"text/css\">".$css_code."</style></head><body>";
// body--------------------------------------------------------
echo "<h2>".$headline_string."</h2>";
echo "Downloads available for: $usrname ($usremail)<br><br>";
print_download_table();
// footer--------------------------------------------------
echo "---!";
echo "</body></html>";
}
?>
Nov 10 '06 #1
Share this Question
Share on Google+
16 Replies


P: n/a
matt wrote:
I have used some free code for listing files for download, but I want to
send an email to the administrator when the file has been downloaded. I
have got some code in here that does it, but it will not print in the
username or email amddress of the person doing the download - which I am
collecting from a form on the previous page. I can get the name and
email address to print out normally, just not into the email sending
body. I have attached code below:
Whooooaa!
<snip unread code>

Let's say you "print out normally the name and email address" with

echo $name;
echo $email_address;

Then, in the mail body, just add those variables;
Where you have (maybe????)

mail($to, $sub, $body, $xtra);

replace with

mail($to, $sub, $body . "\n\n$name $email_address", $xtra);

Voila!
--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 10 '06 #2

P: n/a
Pedro Graca wrote:
matt wrote:
>>I have used some free code for listing files for download, but I want to
send an email to the administrator when the file has been downloaded. I
have got some code in here that does it, but it will not print in the
username or email amddress of the person doing the download - which I am
collecting from a form on the previous page. I can get the name and
email address to print out normally, just not into the email sending
body. I have attached code below:


Whooooaa!
<snip unread code>

Let's say you "print out normally the name and email address" with

echo $name;
echo $email_address;

Then, in the mail body, just add those variables;
Where you have (maybe????)

mail($to, $sub, $body, $xtra);

replace with

mail($to, $sub, $body . "\n\n$name $email_address", $xtra);

Voila!

It still isnt working. Is it because I have it inside a function, and
the function blocks the variables from outside the function going into
the function? I made them global, but it still just prints a blank space.

I have

$usrname = $_POST["usrname"];
$usremail = $_POST["usremail"];

which is the name and email that I want to email to the site admin, then
i have this at the very bottom of the script:

echo "Downloads available for: $usrname ($usremail)<br><br>";

which is not in a function, and displays to the screen OK

but this is inside the 'send email' function which doesnt display, even
when I echo it to the screen:

echo "Downloads available for: $usrname ($usremail)<br><br>";

$from_info = "The following file has been downloaded: $download
User Details $usrname, $usremail";
$subject = "File Downloaded: $download";

mail($admin_email, $subject, $from_info . "\n\n$usrname $usremail",
"From: downloads@--.com.au");

Yet the $download seems to pass into the function and display fine!!

Thanks for your help
Nov 11 '06 #3

P: n/a
matt wrote:
Pedro Graca wrote:
>matt wrote:
>>>I can get the name and
email address to print out normally, just not into the email sending
body.

Then, in the mail body, just add those variables;
Where you have (maybe????)

mail($to, $sub, $body, $xtra);

replace with

mail($to, $sub, $body . "\n\n$name $email_address", $xtra);

It still isnt working. Is it because I have it inside a function, and
the function blocks the variables from outside the function going into
the function? I made them global, but it still just prints a blank space.

I have

$usrname = $_POST["usrname"];
$usremail = $_POST["usremail"];
Well ... $_POST["usrname"] and $_POST["usremail"] are perfectly fine
variables. You don't need to copy them to some other variables and use
the copies instead.
/And/ the $_POST array is a "super global" array, which means it will
exist inside functions, included files, or whetever else you can think
of.

<snip>
$subject = "File Downloaded: $download";

mail($admin_email, $subject, $from_info . "\n\n$usrname $usremail",
"From: downloads@--.com.au");
Use the super global array instead:

mail($admin_email, $subject,
$from_info . "\n\n{$_POST['usrname']}\t\t\t\t{$_POST['usremail']}",
"From: downloads@--.com.au");
Yet the $download seems to pass into the function and display fine!!
I'd have to take a look at your script to understand why.
Maybe tomorrow, no promises.

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 11 '06 #4

P: n/a
Pedro Graca wrote:
matt wrote:
>>Pedro Graca wrote:
>>>matt wrote:

I can get the name and
email address to print out normally, just not into the email sending
body.

Then, in the mail body, just add those variables;
Where you have (maybe????)

mail($to, $sub, $body, $xtra);

replace with

mail($to, $sub, $body . "\n\n$name $email_address", $xtra);

It still isnt working. Is it because I have it inside a function, and
the function blocks the variables from outside the function going into
the function? I made them global, but it still just prints a blank space.

I have

$usrname = $_POST["usrname"];
$usremail = $_POST["usremail"];


Well ... $_POST["usrname"] and $_POST["usremail"] are perfectly fine
variables. You don't need to copy them to some other variables and use
the copies instead.
/And/ the $_POST array is a "super global" array, which means it will
exist inside functions, included files, or whetever else you can think
of.

<snip>
>> $subject = "File Downloaded: $download";

mail($admin_email, $subject, $from_info . "\n\n$usrname $usremail",
"From: downloads@--.com.au");


Use the super global array instead:

mail($admin_email, $subject,
$from_info . "\n\n{$_POST['usrname']}\t\t\t\t{$_POST['usremail']}",
"From: downloads@--.com.au");

>>Yet the $download seems to pass into the function and display fine!!


I'd have to take a look at your script to understand why.
Maybe tomorrow, no promises.
Thanks, I have added in the line you have put there, but it still just
prints a blank space. I appreciate your help.
Nov 11 '06 #5

P: n/a
matt wrote:
Pedro Graca wrote:
>matt wrote:
>>>
Yet the $download seems to pass into the function and display fine!!

I'd have to take a look at your script to understand why.
Maybe tomorrow, no promises.
Thanks, I have added in the line you have put there, but it still just
prints a blank space. I appreciate your help.
Increase the level reporting level of your script.
Add these two lines right after the first php opening tag

error_reporting(E_ALL);
ini_set('display_errors', '1');

When you get it working, remove the lines. Better yet would be to set
error_reporting and related configuration stuff turned on for the
development machine and off for the server.

At some point in your code you call email_admin().
Are the variables $usrname and $usremail set at the time of the call?

echo '<pre>'; var_dump($usrname, $usremail), echo '</pre>';
email_admin($usrname, $usremail);

When I trimmed your code to 50 lines (just the email_admin() and a few
ifs left from the original code, no `global` or $GLOBALS stuff), the
$usrname and $usremail variables were correctly set inside the
admin_email() function.

function email_admin($usrname, $usremail)
{
$usrname = $GLOBALS["usrname"];
$usremail = $GLOBALS["usremail"];
$download = $GLOBALS["download"];

Huh? ??!?!?!?!?
Why are you copying from $GLOBALS to the function parameters?

Sprinkle a few debugging lines throughout the code to find out what it
is doing with the `global` and $GLOBALS stuff.

First define a function for easy debugging:

function debug(&$var, $line) {
echo '<pre>', 'DEBUGGING line ', $line, ': ';
print_r($var);
echo '</pre>';
}

Then use that function in relevant places in your code:

function email_admin($usrname, $usremail)
{
debug($usrname, __LINE__);
$usrname = $GLOBALS["usrname"];
debug($usrname, __LINE__);
// ...
}
The code you posted is a big mess :(
I suggest you break it into (small) functions, stop relying on
register_globals, do not use $GLOBALS or global declarations at all.

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 11 '06 #6

P: n/a
Pedro Graca wrote:
matt wrote:
>>Pedro Graca wrote:
>>>matt wrote:

Yet the $download seems to pass into the function and display fine!!

I'd have to take a look at your script to understand why.
Maybe tomorrow, no promises.

Thanks, I have added in the line you have put there, but it still just
prints a blank space. I appreciate your help.


Increase the level reporting level of your script.
Add these two lines right after the first php opening tag

error_reporting(E_ALL);
ini_set('display_errors', '1');

When you get it working, remove the lines. Better yet would be to set
error_reporting and related configuration stuff turned on for the
development machine and off for the server.

At some point in your code you call email_admin().
Are the variables $usrname and $usremail set at the time of the call?

echo '<pre>'; var_dump($usrname, $usremail), echo '</pre>';
email_admin($usrname, $usremail);

When I trimmed your code to 50 lines (just the email_admin() and a few
ifs left from the original code, no `global` or $GLOBALS stuff), the
$usrname and $usremail variables were correctly set inside the
admin_email() function.

function email_admin($usrname, $usremail)
{
$usrname = $GLOBALS["usrname"];
$usremail = $GLOBALS["usremail"];
$download = $GLOBALS["download"];

Huh? ??!?!?!?!?
Why are you copying from $GLOBALS to the function parameters?

Sprinkle a few debugging lines throughout the code to find out what it
is doing with the `global` and $GLOBALS stuff.

First define a function for easy debugging:

function debug(&$var, $line) {
echo '<pre>', 'DEBUGGING line ', $line, ': ';
print_r($var);
echo '</pre>';
}

Then use that function in relevant places in your code:

function email_admin($usrname, $usremail)
{
debug($usrname, __LINE__);
$usrname = $GLOBALS["usrname"];
debug($usrname, __LINE__);
// ...
}
The code you posted is a big mess :(
I suggest you break it into (small) functions, stop relying on
register_globals, do not use $GLOBALS or global declarations at all.

I seem to have broken the script altogether now, and can't get it to
work again.

You may have an idea, all I am trying to do, is display a list of files
in a directory, then send an email to the admin when one is downloaded.
I didn't write this script from scratch, I found the code that did the
download display on a website, then added the send email function to it
myself. If you know of a better, simpler way to do it, I would be very
much appreciative.
Nov 12 '06 #7

P: n/a
matt wrote:
I am trying to display a list of files
in a directory, then send an email to the admin when one is downloaded.
I wrote this set of functions, just for you :)

<?php
/* ************************************************** ****
This code is in the public domain.
Feel free to use and adapt to your needs.

*** NO GUARANTEES ***

name: file_download.inc.php
version: 20061114
Author: Pedro Graca
************************************************** **** */

######## download_id_is_valid($id, $filelist)
# verifies if the $filelist array has an element
# with the specified $id for index
#
# Returns true or false
#
function download_id_is_valid($id, $filelist) {
if (!$filelist) return false;
if (!isset($filelist[$id])) return false;
return true;
}

######## download_file_is_valid($name)
# verifies if the $name is valid for download
#
# Returns true or false
#
function download_file_is_valid($name) {
clearstatcache();
if (!is_file($name)) return false;
return preg_match('/(?:jpg|png|jpeg|gif|bmp)$/', $name);
}

######## file_list($d)
# builds an array with all valid files in the
# $d directory
#
# Returns the array with the file names
# or false if no valid files found
# Also returns false if the directory could not be read
#
function file_list($d) {
clearstatcache();
if (!is_dir($d)) return false;
$dh = opendir($d);
if (!$dh) return false;
$retval = array();
while (($f = readdir($dh)) !== false) {
if (download_file_is_valid($d . '/' . $f)) {
$retval[] = $f;
}
}
return (count($retval) ? $retval : false);
}

######## send_file_by_id($id, $filelist, $d)
# sends the file $filelist[$id] from the directory $d
# to the client
#
# Returns false if the file to send is invalid
#
function send_file_by_id($id, $filelist, $d) {
if (!download_id_is_valid($id, $filelist)) return false;
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' .
rawurlencode($filelist[$id]) .
'"');
readfile($d . '/' . $filelist[$id]);
return true;
}
?>

And I'd use like this:

<?php
require 'file_download.inc.php';

### some constants
define('DOWNLOAD_DIRECTORY', '.');
define('EMAIL_ADMIN', 'a****@example.com');

# if the directory contents change between requests
# the file sent to the client and the file requested may
# be different. To avoid that, the file list is saved
# in a session variable.
session_start();
if (!isset($_SESSION['files'])) {
$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY);
}

# If the request is for a valid file, send the
# file (and mail the admin) and exit.
if (isset($_GET['id']) && download_id_is_valid($_GET['id'], $_SESSION['files'])) {
if (send_file_by_id($_GET['id'], $_SESSION['files'], DOWNLOAD_DIRECTORY)) {
mail(EMAIL_ADMIN, 'downloads', 'file sent');
exit();
}
}

# display file list
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="dl.php?id=', $k, '">', $f, "</a><br>\n";
}
?>

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 14 '06 #8

P: n/a
Pedro Graca wrote:
matt wrote:
>>I am trying to display a list of files
in a directory, then send an email to the admin when one is downloaded.


I wrote this set of functions, just for you :)

<?php
/* ************************************************** ****
This code is in the public domain.
Feel free to use and adapt to your needs.

*** NO GUARANTEES ***

name: file_download.inc.php
version: 20061114
Author: Pedro Graca
************************************************** **** */

######## download_id_is_valid($id, $filelist)
# verifies if the $filelist array has an element
# with the specified $id for index
#
# Returns true or false
#
function download_id_is_valid($id, $filelist) {
if (!$filelist) return false;
if (!isset($filelist[$id])) return false;
return true;
}

######## download_file_is_valid($name)
# verifies if the $name is valid for download
#
# Returns true or false
#
function download_file_is_valid($name) {
clearstatcache();
if (!is_file($name)) return false;
return preg_match('/(?:jpg|png|jpeg|gif|bmp)$/', $name);
}

######## file_list($d)
# builds an array with all valid files in the
# $d directory
#
# Returns the array with the file names
# or false if no valid files found
# Also returns false if the directory could not be read
#
function file_list($d) {
clearstatcache();
if (!is_dir($d)) return false;
$dh = opendir($d);
if (!$dh) return false;
$retval = array();
while (($f = readdir($dh)) !== false) {
if (download_file_is_valid($d . '/' . $f)) {
$retval[] = $f;
}
}
return (count($retval) ? $retval : false);
}

######## send_file_by_id($id, $filelist, $d)
# sends the file $filelist[$id] from the directory $d
# to the client
#
# Returns false if the file to send is invalid
#
function send_file_by_id($id, $filelist, $d) {
if (!download_id_is_valid($id, $filelist)) return false;
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' .
rawurlencode($filelist[$id]) .
'"');
readfile($d . '/' . $filelist[$id]);
return true;
}
?>

And I'd use like this:

<?php
require 'file_download.inc.php';

### some constants
define('DOWNLOAD_DIRECTORY', '.');
define('EMAIL_ADMIN', 'a****@example.com');

# if the directory contents change between requests
# the file sent to the client and the file requested may
# be different. To avoid that, the file list is saved
# in a session variable.
session_start();
if (!isset($_SESSION['files'])) {
$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY);
}

# If the request is for a valid file, send the
# file (and mail the admin) and exit.
if (isset($_GET['id']) && download_id_is_valid($_GET['id'], $_SESSION['files'])) {
if (send_file_by_id($_GET['id'], $_SESSION['files'], DOWNLOAD_DIRECTORY)) {
mail(EMAIL_ADMIN, 'downloads', 'file sent');
exit();
}
}

# display file list
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="dl.php?id=', $k, '">', $f, "</a><br>\n";
}
?>
Wow. thankyou so much, I will try putting it into use and let you know
how I go.

Nov 15 '06 #9

P: n/a
Pedro Graca wrote:
And I'd use like this:

<?php
<snip>
# display file list
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="dl.php?id=', $k, '">', $f, "</a><br>\n";
No need to hard code the script name here!

echo '<a href="', $_SERVER['PHP_SELF'], '?id=', $k, '">', $f, "</a><br>\n";
}
?>
--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 15 '06 #10

P: n/a
Pedro Graca wrote:
Pedro Graca wrote:
>>And I'd use like this:

<?php


<snip>
> # display file list
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="dl.php?id=', $k, '">', $f, "</a><br>\n";


No need to hard code the script name here!

echo '<a href="', $_SERVER['PHP_SELF'], '?id=', $k, '">', $f, "</a><br>\n";

> }
?>

Hmm I am getting an error to do with headers already being set?

Warning: session_start() [function.session-start]: Cannot send session
cookie - headers already sent by (output started at
/public_html/file_download.php:1) in /public_html/file_download.php on
line 12

Warning: session_start() [function.session-start]: Cannot send session
cache limiter - headers already sent (output started at
/public_html/file_download.php:1) in /public_html/file_download.php on
line 12

Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27

Any ideas?
Nov 15 '06 #11

P: n/a
matt wrote:
Hmm I am getting an error to do with headers already being set?

Warning: session_start() [function.session-start]: Cannot send session
cookie - headers already sent by (output started at
/public_html/file_download.php:1) in /public_html/file_download.php on
line 12
I suppose your line 1 of file_download.php is

<?php

Right?

Did you copy the script directly from my post? With the spaces in front?
The '<' should be the very first character in the file :)

Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27
This warning will go away once you get the headers sorted out.

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 15 '06 #12

P: n/a
Pedro Graca wrote:
matt wrote:
>>Hmm I am getting an error to do with headers already being set?

Warning: session_start() [function.session-start]: Cannot send session
cookie - headers already sent by (output started at
/public_html/file_download.php:1) in /public_html/file_download.php on
line 12


I suppose your line 1 of file_download.php is

<?php

Right?

Did you copy the script directly from my post? With the spaces in front?
The '<' should be the very first character in the file :)
>>Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27


This warning will go away once you get the headers sorted out.
Ok fixed that, not just this error:

Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27
Nov 15 '06 #13

P: n/a
matt wrote:
Pedro Graca wrote:
>>
This warning will go away once you get the headers sorted out.
Ok fixed that, not just this error:

Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27
Oops ... /That/ wasn't supposed to happen :)

New version of file_download.inc.php (no spaces in front); there's also
a new version of the 'controlling' script. I'll post it in another
article with my reasoning for why the first version failed.

<?php
/* ************************************************** ****
This code is in the public domain.
Feel free to use and adapt to your needs.

*** NO GUARANTEES ***

name: file_download.inc.php
version: 20061115
Author: Pedro Graca

History:
version 20061115
added regexp as a parameter to
download_file_is_valid() and file_list()
removed unnecessary clearstatcache() from
download_file_is_valid()

version 20061114
first draft
************************************************** **** */

######## download_id_is_valid($id, $filelist)
# verifies if the $filelist array has an element
# with the specified $id for index
#
# Returns true or false
#
function download_id_is_valid($id, $filelist) {
if (!$filelist) return false;
if (!isset($filelist[$id])) return false;
return true;
}

######## download_file_is_valid($name, $rx)
# verifies if the $name is valid for download.
# validity is checked with the regualr expression $rx
#
# Returns true or false
#
function download_file_is_valid($name, $rx) {
if (!is_file($name)) return false;
return preg_match($rx, $name);
}

######## file_list($d, $rx)
# builds an array with all valid files in the
# $d directory.
# File validity is tested with the regular expression $rx.
#
# Returns the array with the file names
# or false if no valid files found
# Also returns false if the directory could not be read
#
function file_list($d, $rx) {
clearstatcache();
if (!is_dir($d)) return false;
$dh = opendir($d);
if (!$dh) return false;
$retval = array();
while (($f = readdir($dh)) !== false) {
if (download_file_is_valid($d . '/' . $f, $rx)) {
$retval[] = $f;
}
}
return (count($retval) ? $retval : false);
}

######## send_file_by_id($id, $filelist, $d)
# sends the file $filelist[$id] from the directory $d
# to the client
#
# Returns false if the file to send is invalid
#
function send_file_by_id($id, $filelist, $d) {
if (!download_id_is_valid($id, $filelist)) return false;
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' .
rawurlencode($filelist[$id]) .
'"');
readfile($d . '/' . $filelist[$id]);
return true;
}
?>

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 15 '06 #14

P: n/a
matt wrote:
Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27
When the

$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY, FILE_VALIDITY_RX);

fails, for whatever reason, $_SESSION['files'] would be false.
When $_SESSION['files'] is false, the foreach() produces that warning.

In the new 'controlling' script I added a check for $_SESSION['files']
and introduced the regular expression to check validity of files as
another define'd constant.

Hope it works now.



<?php
require 'file_download.inc.php';

### some constants
define('DOWNLOAD_DIRECTORY', '.');
define('EMAIL_ADMIN', 'a****@example.com');
### The regular expression will match all files with png, gif, jpg or
### bmp extension, in a case insensitive manner
define('FILE_VALIDITY_RX', '/\.(?:png|gif|jpg|bmp)$/i');

# if the directory contents change between requests
# the file sent to the client and the file requested may
# be different. To avoid that, the file list is saved
# in a session variable.
session_start();
if (!isset($_SESSION['files'])) {
$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY, FILE_VALIDITY_RX);
}

# If the request is for a valid file, send the
# file (and mail the admin) and exit.
if (isset($_GET['id']) && download_id_is_valid($_GET['id'], $_SESSION['files'])) {
if (send_file_by_id($_GET['id'], $_SESSION['files'], DOWNLOAD_DIRECTORY)) {
mail(EMAIL_ADMIN, 'downloads', 'file sent');
exit();
}
}

# display file list links
if ($_SESSION['files']) {
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="' . $_SERVER['PHP_SELF'] . '?id=', $k, '">', $f, "</a><br>\n";
}
} else {
echo "No files available to download.<br>\n";
}
?>

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 15 '06 #15

P: n/a
Pedro Graca wrote:
matt wrote:
>>Warning: Invalid argument supplied for foreach() in
/public_html/file_download.php on line 27


When the

$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY, FILE_VALIDITY_RX);

fails, for whatever reason, $_SESSION['files'] would be false.
When $_SESSION['files'] is false, the foreach() produces that warning.

In the new 'controlling' script I added a check for $_SESSION['files']
and introduced the regular expression to check validity of files as
another define'd constant.

Hope it works now.



<?php
require 'file_download.inc.php';

### some constants
define('DOWNLOAD_DIRECTORY', '.');
define('EMAIL_ADMIN', 'a****@example.com');
### The regular expression will match all files with png, gif, jpg or
### bmp extension, in a case insensitive manner
define('FILE_VALIDITY_RX', '/\.(?:png|gif|jpg|bmp)$/i');

# if the directory contents change between requests
# the file sent to the client and the file requested may
# be different. To avoid that, the file list is saved
# in a session variable.
session_start();
if (!isset($_SESSION['files'])) {
$_SESSION['files'] = file_list(DOWNLOAD_DIRECTORY, FILE_VALIDITY_RX);
}

# If the request is for a valid file, send the
# file (and mail the admin) and exit.
if (isset($_GET['id']) && download_id_is_valid($_GET['id'], $_SESSION['files'])) {
if (send_file_by_id($_GET['id'], $_SESSION['files'], DOWNLOAD_DIRECTORY)) {
mail(EMAIL_ADMIN, 'downloads', 'file sent');
exit();
}
}

# display file list links
if ($_SESSION['files']) {
foreach ($_SESSION['files'] as $k=>$f) {
echo '<a href="' . $_SERVER['PHP_SELF'] . '?id=', $k, '">', $f, "</a><br>\n";
}
} else {
echo "No files available to download.<br>\n";
}
?>
Thanks again, I really appreciate the work you put in, it's going now,
working perfectly!
Nov 16 '06 #16

P: n/a
One more change :)

matt wrote:
Pedro Graca wrote:
<snip>
># If the request is for a valid file, send the
# file (and mail the admin) and exit.
if (isset($_GET['id']) && download_id_is_valid($_GET['id'], $_SESSION['files'])) {
if (send_file_by_id($_GET['id'], $_SESSION['files'], DOWNLOAD_DIRECTORY)) {
mail(EMAIL_ADMIN, 'downloads', 'file sent');
exit();
}
else {
## send_file_by_id() failed. Let the user know
echo "Download could not be started. Try again.<br>\n";
## and continue to display file list links
}
>}

# display file list links
<snip>
Thanks again, I really appreciate the work you put in, it's going now,
working perfectly!
At last! Thank you for the feedback.

--
I (almost) never check the dodgeit address.
If you *really* need to mail me, use the address in the Reply-To
header with a message in *plain* *text* *without* *attachments*.
Nov 16 '06 #17

This discussion thread is closed

Replies have been disabled for this discussion.