Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to write an email script that goes to download page? 5

Status
Not open for further replies.

bazmanblue

Programmer
Sep 20, 2006
13
GB
hello everyone nice to meet you all. i am trying my hardest to find a script that allows people to enter five bona fied email addreses and then click the submit button which takes them to a download page for a free ebook. Could anyone point me in the right direction. thanks in advance
barry

 
Hi,
I once made a script like this, took me about 20-30 minutes.

How it works:
First there is an upload section, where files get a row in the table (mysql). They there get file-text, commentary, path to file, etc.

Then, I made a form where they had to input theire email adress, name, phone number, etc.

When they did that, they where registerred in a table.
There was also put a row in a "downloads" table, which tied them, as user, to the file they wanted to download (the file_id).

When the form was submitted, it instantly sent an email to the email they registerred with.

What was in that email, was almost like an activation link, which you get on forums. There was a download id.

When the page was loaded, with download it, the file was set status as downloaded (which means the file cannot be downloaded, without requesting new download on the download-page).

It's not exactly what you want, but it's up the same ally.
Be inspired by other functions which are similar, like forum activation links, etc.

Be aware of the fact that other users can use your system to spam, so try to protect it from spambots, etc. Do not make it easy to submit twice, etc.

I made some tutorials on those "enter text as seen on image", which I can try to find, if you are interested.

Good luck!

Olav Alexander Mjelde
Admin & Webmaster
 
If you have some tutorials that would be great thanks
 
i had something similar that i developed for a law firm. i've made a couple of changes. have a look at
no files are actually on the server for download and there is no validation that an email is real, only that the address is well formed.

is this what you were after?
 
@jpadie: the problem with your script, is that users can bookmark/publish the url and then suddenly google has indexed the download-page.

eg. if I used your script for video-downloads, I guess it would take 2 days for me to be listed on google, for some "video download list", on x amount of forums.

The "download once" script is a bit more work to use, but at the same time, each download has it's unique ID and will only work one time.

dis-advantage is if you get timeout, you have to once again request download.

However, one could choose to let the members keep session "forever" and maybe expand the users ability to login,etc. but still demand that he requests a download.

The reason I used download link thru email, was due to the fact that if he provides a fake email, he wont accept any links for downloads.

You can "cheat" with htaccess and apache, make "fake files". I have done this with images in the past, where as images are called randomint, like so: 1231239129391239123.jpg , but in the browser, it looks like: images/p_<integer for image>/google_search_terms.jpg

The same can be done for the files, as I think that's better than moving/copying/deleting files for each request.

The end time user will (maybe) think he is accessing a real url and it seems as the file gets deleted afterwards.

You can then make your system simply point the file to a dummy-file, when the file has been downloaded..

eg. a file which contains "you have to request a new download on our webpage:
Olav Alexander Mjelde
Admin & Webmaster
 
Code:
@jpadie: the problem with your script, is that users can bookmark/publish the url and then suddenly google has indexed the download-page.

i'm surprised you think that. you should be able to download only once for each set of 5 emails you upload. that was the original design of the script. the counter is currently not reset because no files are available for download. i'll add a dummy file and you can try again.
 
great tips people. thanks for this. this is exactly what im after. do you havethe script you used. also im not sure how you set up a download script for a pdf? if i could incoprorate the download once script that would be magnificent dabutcher?
 
ive given you both a star. i hope you can let me see your script thanks
 
i've posted the script below. as it's culled from a script i wrote for a client that i was hosting there is no source code commentary in it.

Some health warnings:

Whilst i often provide full code in this forum I try to make sure that it is commented and described so that people learn from the code rather than just use it. Sorry if this sounds patronising - it's not intended to be.

Also, i use what others on this forum would call non-standard syntax if they're being polite, and something far worse after a beer. Don't take this code as a paragon of best practice, most coders prefer to use curly-braces instead of the colon ... end syntax (the "alternative syntax"). Equally, i am sure that it can be improved upon by members of this forum with ease.

but hopefully the script is sufficiently broken down into component functions that you get an idea for their interaction and can work things out for yourself. If not, post back in this thread.

to configure:
1. alter the array at the top of the code to add files to the download links. the "application" will handle any filetype without changes being necessary. you can add more files just by adding inner arrays.
2. make sure that you specify the path to the files in the function called serveFile(). the files should be stored outside the webroot or in a directory that you protect with .htaccess (add DENY FROM ALL as a directive in the htaccess file).

you can, of course, change the html at will but you might want to familiarise yourself with the heredoc syntax first. check out the manual on this.

as the code is culled and changed from its original, there may be errors. just post back.

now the code
Code:
<?
	session_start();
	if(!isset($_SESSION['canDownload'])) $_SESSION['canDownload'] = false;
	$filesAvailableForDownload = 
			array(	
				array(
					"filename"=>"somefile.doc",
					"description"=>"a decent description of the file"
					),
				array(
					"filename"=>"someotherfile.doc",
					"description"=>"an equally good description"
					)
				);
				
	$validEmails=array();	
	
	if (isset($_GET['action']) && $_GET['action'] == "download"):
		if (canDownload()):
			$err = serveFile();
			if (!$err):
				die ("there has been a problem");
			endif;
				
		else:
			header("Location=".$_SERVER['PHP_SELF']);
			exit;
		endif;
	endif;
	$msg = validateForm();
	if($msg === true):
		writeaddressestolist();
		setSessionUID();
		showDownloadLinks();
		exit;
	else:
		displayForm($msg);
		exit;
	endif;
	

function displayForm($msg=""){
	$email =array("","","","","","");
	if (isset($_POST['email'])) $email=$_POST['email'];
	$form = "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">\r\n";
	if (!isset($_SESSION['uid'])) setSessionUID();
	for ($i=1; $i<=5; $i++):
		$form .= <<<EOL
		Email Address $i <input type="text" name="email[]" value="{$email[$i-1]}" /><br/>
EOL;
	endfor;
	$form .= "<input type=\"hidden\" name=\"uid\" value=\"".$_SESSION['uid']."\" />";
	$form .= "<input type=\"submit\" name=\"submit\" value=\"upload\"/>\r\n</form>";
	echo $msg;
	echo $form;
}
function alreadyPosted(){
	if (!isset($_POST['uid'])) return true;
	if (!isset($_SESSION['uid'])) return true;
	if ($_POST['uid'] === $_SESSION['uid']):
		return false;
	else:
		return true;
	endif;
}
function setSessionUID(){
	$_SESSION['uid'] = uniqid("uid_", true);
}
function validateForm(){
	$msg = "";
	global $validEmails;
	if (!isset($_POST['email'])) return "";
	if (alreadyPosted()):
		setSessionUID();
		unset($_POST);
		return "You have already posted this form or there has been an error.  You may not submit the same data twice";
	endif;
	foreach($_POST['email'] as $key=>$email):
		if (empty($email)):
			$msg .= "You have not filled in Email Address ". ($key + 1) ."<br/>";
		elseif(!isValidEmail($email)):
			$msg .= "Email Address " . ($key + 1) . " is invalid<br/>";
		elseif(in_array($email, $validEmails)):
			$msg .= "Email Address " . ($key + 1) . " is a duplicate of an email you have already included<br/>";
		else:
			$validEmails[] = $email;
		endif;
	endforeach;
	if(empty($msg)):
		return true;
	else:
		return $msg;
	endif;
}
function writeAddressesToList(){
	global $validEmails;
	$list = "list.txt";
	$fh = fopen($list, "a+");
	$emails = implode("\r\n", $validEmails);
	fwrite($fh, $emails);
	fclose($fh);
}
function isValidEmail($email){
	//this function is taken from the php manual, user notes.
       $p = '/^[a-z0-9!#$%&*+-=?^_`{|}~]+(\.[a-z0-9!#$%&*+-=?^_`{|}~]+)*';
	$p.= '@([-a-z0-9]+\.)+([a-z]{2,3}';
	$p.= '|info|arpa|aero|coop|name|museum)$/ix';
	return preg_match($p, $email);
}
function showDownloadLinks(){
	global $filesAvailableForDownload;
	foreach ($filesAvailableForDownload as $file):
		echo "<a href=".$_SERVER['PHP_SELF']."?action=download&file=".$file['filename'].">".$file['description']."</a><br/>";
	endforeach;
	$_SESSION['canDownload'] = true;
}
function canDownload(){
	if ($_SESSION['canDownload'] === true):
		return true;
	else:
		return false;
	endif;
}
function serveFile(){
	global $filesAvailableForDownload;
	$path = "./";
	if (!isset($_GET['file'])) return false;
	$test=false;
	foreach($filesAvailableForDownload as $file):
		if (in_array($GET['file'], $file)):
			$test=true;
			break(0);
		endif;
	endforeach;
	if ($test === true) return false;
	header('Content-type: application/octet-stream');
	header('Content-Disposition: attachment; filename="'.$_GET['file'].'"');
	header('Content-Length: ' . filesize($path.$filename));
	readfile($path.$filename) or die("cannot open file");
	$_SESSION['canDownload'] = false;
	return true;
}
?>
 
As Jpadie said, I have to say the same.

This code is old, lacks good commenting, etc.
The reason is quite simple, I used 20-30 minutes on this..
Including the upload form, the database-structure, etc.

Anyhow, php is quite easy to read, if you know some php.

YOU SHOULD:
1. Update the queries in my script, to use sprintf
2. striptags() on all variables which are near the db
3. trim() on variables
4. do better validation of fields
5. HTMLENCODE the variables
6. more stuff, which I probobly forgot


Anyhow, here is the download section of the script:
Code:
<?php

// connect to the database
mysql_connect ('host', 'user', 'password');
// select database
mysql_select_db ("database");

if (isset($lid))  {
  /* 
   This is a function that corresponds the id to a filename.  You
   may get the filename from the db or whatever..
  */

  $filename = getFilenameFromID($lid, $user);
  
		
  // let's strip the filename, to get a real name without path
  $fnam = substr($filename, (strrpos($filename, "/") + 1), strlen($filename)); 
  $furl = substr($filename, 0, (strrpos($filename, "/") + 1)); // returns real filename

  
  // now set the right headers...
  header("Content-type: application/octet-stream");
  header("Content-Disposition: attachment; filename=$fnam");
  header("Content-Location:$furl" );
  header("Content-Transfer-Encoding: binary");

  if (is_file($furl. $fnam)) {
  $handle = fopen($furl . $fnam, "rb");	
  $content = fread($handle, filesize($furl . $fnam)); 
  fclose($handle);
  }
  else {
  if ($fnam == "404.txt") {
      $content = "Download no longer active, please request new download.";
    }
  else {
      $content = "Missing or corrupt file, please let us know which file you tried to download";
    }
  }
  // now print the file..
  print $content;
  exit();
  }
session_start();
 if (isset($_POST['from_name'])) {
 $_SESSION['from_name'] = $from_name;
 }
 if (isset($_POST['from_company'])) {
 $_SESSION['from_company'] = $from_company;
 }
 if (isset($_POST['from_phone'])) {
 $_SESSION['from_phone'] = $from_phone;
 }
 if (isset($_POST['from_email'])) {
 $_SESSION['from_email'] = $from_email;
}

function getFilenameFromID($file_id, $from)
{
// kjør query mot db, WHERE id = '$file_id'
  $result = mysql_query("SELECT * from tbl_attatchment, tbl_downloads WHERE 
  		att_lid =  d_id_f_id AND d_by_email = '" . $from . "' AND 
  		d_active = 1 AND att_lid = '$file_id'");
  if (mysql_num_rows($result) == 1) {
  while($row = mysql_fetch_array($result)) {
    $f = $row['att_url'];
    }
  }
  else {
    $f = "/404.txt";
    }
    
      $resupdt = mysql_query("UPDATE `tbl_downloads` SET `d_dt` = NOW( '20050820135738' ) ,
	`d_active` = '0' WHERE `d_id_f_id` = '$file_id' AND 
	d_by_email = '" . $from . "' AND d_active='1' LIMIT 1");

  return $f;
}

if ($rf != "") {
$_POST['key'] = $_SESSION['key'];
  if( $_POST['action'] == "Send") {

  
  
        $res = mysql_query("SELECT * FROM `tbl_downloads` WHERE d_by_email = '". $_SESSION['from_email'] . "' 
        		AND d_active = '1' AND `d_id_f_id` = '". $rf . "'");
        if (mysql_num_rows($res) < 1) {
	  $results = mysql_query("INSERT INTO `tbl_downloads` ( `d_id` , `d_id_f_id` , `d_dt` , `d_by_name` , `d_by_phone` , `d_by_company_name` , `d_by_email` , `d_active` ) 
	VALUES (
	'', '" . $rf ."', NOW( ) , '" . $_SESSION['from_name'] . "', '" . $_SESSION['from_phone'] . "', '" . $_SESSION['from_company'] . "', '" . $_SESSION['from_email'] . "', '1');") OR DIE ("foo"); 

	// send mail with link
	        $toname = $_SESSION['from_name'];
	        $toadress = $_SESSION['from_email'];
	        $subject = "YourCompanyName - Requested Download Link";
	        $message = "Hi, " . $_SESSION['from_name'] . 
	                   " / " . $_SESSION['from_company'] . 
	                   "\n\nThe file you requested for download, can be accessed here: " .
	                   "\n[URL unfurl="true"]http://www.yourdomain.tld/downloads/?lid="[/URL] . $rf . "&user=" . $_SESSION['from_email'] . 
	                   "\n\n The download url can only be used once.";
	      mail($_SESSION['from_email'], $subject, $message);
	}

	$rf = "";
	$_POST['key'] = $_SESSION['key'];
	


    }
  }
?>
<?php
echo $_SESSION['fubar'];

if (isset($submit)) {
  if ($submit == "logout") {
      unset($_SESSION['key']);
    }

  }

if ($_SESSION['key'] != $_POST['key'] || (!($_SESSION['key']))) {
  $_SESSION['key'] = substr(md5(time()), 0, 6);
  echo "<p>To access our contact-form, enter the security-code as seen below:</p> 
  <form action=\"\" method=\"post\">
  <p>
  <strong>Security-Code:</strong><br />
  <img src=\"/sec.jpg\" />
  </p>
  <p>
  <strong>Type Security-Code, as seen above:</strong><br />
  <input type=\"text\" name=\"key\" />
  <input type=\"submit\" name=\"submit\" value=\"submit\" />
  </p>
  </form>";
  exit();
  }
else {

if ($from_email != "" && $enquery != "" || !isset($rf) || $rf == "")  {
       // session_destroy();
       if (isset($from_name)) {
       $_SESSION['from_name'] = $from_name;
       }
       if (isset($from_company)) {
       $_SESSION['from_company'] = $from_company;
       }
       if (isset($from_phone)) {
       $_SESSION['from_phone'] = $from_phone;
       }
       if (isset($from_email)) {
       $_SESSION['from_email'] = $from_email;
	}
       $_POST['key'] = $_SESSION['key'];

        $toname = "yourCompanyName";
        $toadress = "reply.Adress@yourdomain.tld";
        $subject = "YourCompanyName - Feedback form";
        $message = "Name: " . $from_name . 
                   "\nCompany: " . $from_company . 
                   "\nPhone: " . $from_phone .
                   "\nEmail: " . $from_email .
                   "\n\n\n" . $enquery;
        /*if (mail($toadress, $subject, $message)) {
        echo "Thank you for your enquery!<br />We will get back to your shortly.";
        }
        else {
        echo "Oops! Something went wrong!";
        }*/
     // start download
  $result = mysql_query("SELECT * from  tbl_attatchment 
ORDER BY att_title ASC") or die (mysql_error());
  while($row = mysql_fetch_array($result)) {
  
 		
    // let's strip the filename, to get a real name without path
    $fnam = substr($filename, (strrpos($filename, "/") + 1), strlen($filename)); 
    $furl = substr($filename, 0, (strrpos($filename, "/") + 1)); // returns real filename
  
  echo $furl . $fnam;
   
  ?>
<p>
  <strong>Title: </strong><?=$row['att_title'] ?><br />
  <strong>Description: </strong>  <?=$row['att_description'] ?><br />
    <a href="?rf=<?=$row['att_lid'] ?>">Request File</a></td>
</p>
<?
  } 
?>
</table>
<?php
// end download
  }

if ($rf != "") { // show form
$_POST['key'] = $_SESSION['key'];
?>
<strong>Information:</strong>
After requesting file-download, please look in your mail inbox.<br />
You will recieve an e-mail with a download URL.
<form action="?" method="post">
<table border="1">
<tr><td>
<p>
Your name:<br />
<input type="text" name="from_name" value="<?=$_SESSION['from_name']?>" />
</p>
<p>
Company Name:<br />
<input type="text" name="from_company" value="<?=$_SESSION['from_company']?>" />
</p>
<p>
Phone#:<br />
<input type="text" name="from_phone" value="<?=$_SESSION['from_phone']?>" />
</p>
<p>
<strong>Your e-mail adress*:</strong><br />
<input type="text" name="from_email" value="<?=$_SESSION['from_email']?>" />
<input type="hidden" name="rf" value="<?=$rf?>" />
</p>
</td>
<td></td>
</tr>
<tr>
<td colspan="2">
<p>
<strong>Comments / Questions*:</strong><br />
<textarea name="enquery" cols="45" rows="10"><?=$enquery?></textarea><br />
<strong>* Required fields</strong>
</p>
<input type="hidden" name="key" value="<?=$key?>" />
<input type="submit" name="action" value="Send" />
<input type="reset" value="Clear" />
</td>
</tr>
</table>
</form>
<?php
    }
  }
?>

I will post atleast one more section (upload), *i think*

depends on how integrated it is, but I seem to remember it's a "loose" script.

this script needs a database too and I dont know if I can provide you with the structure.. You should however be able to read the queries to figure it out for yourself..

Also, here the script is in the root of the website and the files are stored in /pub/download/

the file here, is called download (without extension)

You also need a htaccess file I have, which I'll post.

Olav Alexander Mjelde
Admin & Webmaster
 
The upload system -- Also needs hardening

Code:
<?php
require("path_to/login.php");
// connect to the database
mysql_connect ('host', 'username', 'password');
// select database
mysql_select_db ("database");

// ####################################
// start download
$result = mysql_query("SELECT * from  tbl_attatchment") or die (mysql_error());
while($row = mysql_fetch_array($result)) {
$dbfiles .= " " . $row['att_url'];
}
$dbfiles = explode(" ", ltrim($dbfiles));
// ####################################

if (isset($_POST['insert'])) {
	 $result = mysql_query("INSERT INTO `tbl_attatchment`
	 			(`att_lid` , `att_title` , `att_description` ,
	 			 `att_text` , `att_url` , `att_type_id_id_type` )
				VALUES ('', '" . $_POST['title'] . "', '" . $_POST['description'] . "',
				'', '" . $_POST['file'] . "', '0');") OR DIE ("foo");
	header("HTTP/1.1 301 Moved Permanently");
	header("location: upload.php");
	header("Connection: close");

  }

$dir = "pub/download/";

// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
   if ($dh = opendir($dir)) {
       while (($file = readdir($dh)) !== false) {
           if ($file != ".." && $file != ".") {
             $hdfiles .= " $dir$file";
             //echo "filename: $dir$file\n<br />";
           }
           //echo mysql_num_rows($result);
       }
       closedir($dh);
   }
}
$hdfiles = explode(" ", ltrim($hdfiles));
$result = array_diff($hdfiles, $dbfiles);

if (count($result) > 0) {
         for ($i = 0; $i < count($result); $i++) {
		   if ($i == 0) {
		   $foo =  current($result);
	       echo "<form action=\"\" method=\"post\">
	       		 File:&nbsp;&nbsp;<a href=\"$foo\" target=\"_blank\">$foo</a><br />
	             Title: <input type=\"text\" name=\"title\" /><br />
	             Description: <br /><textarea name=\"description\" rows=\"5\" cols=\"30\" /></textarea><br />
	             <input type=\"hidden\" name=\"file\" value=\"{$foo}\" />
	             <input type=\"submit\" name=\"insert\" value=\"Insert\" />
	             <hr /></form>";
	       }
	       else {
	       $foo = next($result);
	       echo "<form action=\"\" method=\"post\">
	       		 File:&nbsp;&nbsp;<a href=\"$foo\" target=\"_blank\">$foo</a><br />
	             Title: <input type=\"text\" name=\"title\" /><br />
	             Description: <br /><textarea name=\"description\" rows=\"5\" cols=\"30\" /></textarea><br />
	             <input type=\"hidden\" name=\"file\" value=\"{$foo}\" />
	             <input type=\"submit\" name=\"insert\" value=\"Insert\" />
	             <hr /></form>";
	       }
	     }

  
  }

?>

It works quite easy:
upload files via ftp, the upload.php scans the dir for files it does not have in the db. You can then add text to the files!

Sorry, I cannot provide the htaccess file, as I'm unable to locate it :S

As stated above: NEEDS HARDENING
Secure all variables, etc. etc. dont use it as is, I used 20-30 mins on this, the previous, htaccess and the database-design.. so it's not exactly premium coded, lol...

Also a long time since I made it, maybe 2 yrs..

Olav Alexander Mjelde
Admin & Webmaster
 
Here is sec.jpg (not really a jpg file)
Code:
<?php
session_start();

if ($_SESSION['key']) {
  header("Content-type: image/png");
  $string = $_SESSION['key'];
  $im    = imagecreatefrompng("images/bg.png");
  $white = $white = imagecolorallocate($im, 192, 255, 0);
  $px    = (imagesx($im) - 7.5 * strlen($string)) / 2;
  $h = (imagesy($im) - 7.5) / 2;
  imagestring($im, 4, $px, $h, $string, $white);
  imagepng($im);
  imagedestroy($im);
  }
?>

it's really important that sec.jpg has no trailing whitespace! you also have to define in htaccess to run it as php

Olav Alexander Mjelde
Admin & Webmaster
 
Think im getting you both. can the emails that are typed in be sent an automated email saying that they have been recomended to come to the website by the person submitting the form. so the persons email address needs to be taken aswell. kind of like one of those automated e-cards but with the submit button taking them to the download page aswell as sending the automated emails?
 
btw:
you first make the dirs, make the files..

then you upload files into pub/upload
after that, you have to run upload.php, to name the files with titles/text.When that is done, the download script will work.

The downloadscript will present the downloads in a list, after the user has entered the code, as seen on the image.

When he sees it, he can request it for download.
He then saves his info in the db, with a unique download id.

This id he recieves in his email, which he then can click.
That page will then query the table for a row with him and his id. If that download is active, it pushes it thru and then sets it to inactive.

Very simple script actually, quite messy programming.
I hope you can slaughter it and sew it back together in a better shape.. you can almost use it as it is, but you need a htaccess to define that sec.jpg is php, that download without extension is php and you have to operate a bit in the code, add your domain, etc.

Olav Alexander Mjelde
Admin & Webmaster
 
There is no problem sending as many emails as you wish..
You could make another system, like my download system, only you make the table for refferer.

You can then make it so that when I reffer jpadie, I actually insert a row in the table. Then I get an email, where I have to confirm that I actually pressed the refferal button.

When I press that link, it will query the table for active refferals.

If inactive, display error, else email the people I want to reffer.

When they are reffered, you still keep them in the db, both for staticstics and most importantly to prevent the spamming possibilities.

When other people want to reffer jpadie, the system will query the db for the emails and see that jpadie has already been reffered.

You could then take checks in sql (to_days) and have a rule, let's say that one person cannot be reffered more than 1 time per 100 days.

Olav Alexander Mjelde
Admin & Webmaster
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top