Im making a website for a band, and they are giving out their EP for free, but they want it so the user has to enter their email address before downloading... How would this be done in php?
The downloadable should be placed out of the reach of web user but within your PHP script reach. Then once user is done filling form, you can then force download the file contents by opening it locally using say "fopen".
Update (Adding Sample Code):
Suppose the file is "txt.txt" which could be in your script reach. You will open it, read and then put the contents after calling header and telling it that its an attachment (force download)
$done = true;
if($done == true){
$filename = "txt.txt";
$conn = fopen($filename,"r");
$contents = fread($conn, filesize($filename));
fclose($conn);
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="downloaded.txt"');
echo $contents;
}
If you're storing the emails somehow, then simply set a $_SESSION value when they submit their email, and when writing the page, if the part of the $_SESSION value has been set, then provide a link to the media.
To start a session & set the value:
session_start();
$_SERVER['hasEmail']=true;
And in the page:
session_start();
if ($_SERVER['hasEmail']) {
//Provide link
}
You could then also have the media link take you to a PHP script which uses fopen() or similar to get the file from another location on your filesystem out of reach of the user, such as one under .htaccess blocking, and it'll only provide the media is the $_SESSION value is set.
Related
I need a method to protect the download URL of a file from being seen by the downloader.
The idea is that the user is given a download link after paying, but to stop them spreading the URL among their friends who haven't paid.
What are some common solutions to this? Possibly changing file name?
(I can do PHP, and mySql this post is for methods really)
If users have an account on your site, stock in your DB if they paid the download. Then give them a link such as download.php where you verify if they paid, and if yes, do a location to the file. Example for a .pdf :
if($userpaid === true) {
$filename = 'congrat-you-paid-it.pdf'; //Name to display
$file = './download/pdf/secretlink.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="'.$filename.'"');
header('Content-Length: ' . filesize($file));
#readfile($file);
exit;
}
One solution could be to use SESSION or a similar temporary storage and generate download URLs at run-time. So clicking on the URL again may not work.
Also, direct access to the files should not be allowed.
Create a token. Store at your end and send with file URL as well. When user clicks the URL match the token and allow the download, then remove token from your storage.
You've to generate new token every time registered user wants to download though.
Use sessions is quick and easy, for better security, what you can do is:
Put the actual file in a separate folder and put a .htaccess in it to
only allow the script to access that file.
Then generate a random unique variable
Then make a temp file with that name and give the link to it to the
client
Finally run a cron job to delete the unnecessary created files.
For an insurance company, I've created PDF forms of their various insurance applications. These will be available on their website (when it is done). Each form, being in PDF, looks exactly like the printed version of the application. The idea is that a user fills it out online, hits the (visible but unprintable) "Submit" button at the bottom of the form, and the entire completed PDF is sent to the company. That way they can print it out, and carry on with their current paper filing system.
I experimented with using a "mailto:..." URL for the Submit button, but that requires an external mail program. It also gives the attached PDF a random temp filename.
Therefore, I'd like to send the PDF to a php script, change the name, and email it to the company from there. I played with it a bit, and I can reach the destination script, but I have no idea what happens to the PDF. I expected it to show up in $_FILES, but nothing.
Saving to a database is not an option.
When preparing the PDF form, you can choose how you would like to submit: as an HTML form (as Sepodati said), as XML data, as FDF (which only sends data, and will open the original PDF when displaying the data), or as a completed PDF. For ease of use for the site owners, who are not computer savvy, I'm going to send them a completed PDF that they can print.
So, the same question remains: where does my PDF file go when I get to my destination script?
I'm submitting the PDF via a Submit button on the PDF itself. You'll have to be familiar with PDF forms to understand this. For the URL, I put the destination PHP script.
In my destination script, I tried the following
PHP Code:
reset ($_FILES);
while (list ($key, $val) = each ($_FILES)) {
echo "$key => $val<br />\n";
}
I did this for $_FILES, $_GET, $_POST, and $_REQUEST. Nothing came up, as though each array was empty. I might have done this wrong, though.
I put phpinfo() in the script, and these vars appear related to the PDF...
_SERVER["CONTENT_LENGTH"] = 37722
_SERVER["CONTENT_TYPE"] = application/pdf
_SERVER["HTTP_USER_AGENT"] = Mozilla/4.0 (compatible; Adobe Acrobat Control Version 5.00 for ActiveX)
_SERVER["REQUEST_METHOD"] = POST
The content length is approximately the size of the PDF.
Something else I didn't notice before is that upon submission, Internet Explorer displays this page (or a name like it):
C:\WINDOWS\TEMP\pa003773.html
This page contains all the output from my script.
It's very interesting that it's supposed to send the entire PDF. I would be interested in knowing how it does that because I've searched the Adobe site for information on how to submit an entire PDF file by clicking a button on the PDF form.
The only thing I found on their site was information about the FDF and XFDF formats. Both of these formats have to be parsed in some way by your form handler script and aren't included in $_FILES the way a file is uploaded when you select the file from the filesystem.
$fptr = fopen("temp.fdf", "w");
fputs($fptr, $HTTP_RAW_POST_DATA);
fclose($fptr);
This is a really old post so I'm sure you've gotten your answer by now but here's what worked for me in case anyone else stumbles across this in the future.
BTW- this only works for if you are submitting the entire PDF with the form fields completed.The address you would put on your submit button would be something like http://youserver.com/lib/php/formProcess.php?email=to#company.com&formName=Asset%20Inventory
<?php
ob_start();
$file = file_get_contents("php://input"); //Gets binary PDF Data
$time = microtime(true);
//Names pdf file based on the time to the microsecond so nothing gets overwritten. Obviously you can change this to whatever you want or do something like $_REQUEST['formName'] and just include the form name in your URL from your pdf submit button
$newfile = "forms/" . $time . ".pdf";
$worked = file_put_contents($newfile, $file); //Creates File
ob_end_clean();
//Upon completion you can either return XFDF to update a field on your form or display a PDF document. I chose the PDF route because it worked for our situation.
$successFile = 'success.pdf';
$errFileFile = 'error.pdf';
require 'PHPMailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSendmail();
$mail->setFrom('From email address', 'from name');
$mail->addReplyTo('Reply to email', 'Reply to name');
$mail->addAddress($_REQUEST['email']); //get email from URL- alternately you can just hardcode in an address
$mail->addAttachment( $newfile );
$mail->isHTML(true);
$mail->Subject = 'New form submission';
$mail->Body = 'A new form has been submitted.';
if(!$mail->send()) {
header('Content-type: application/pdf');
readfile($errFile);
} else {
header('Content-type: application/pdf');
readfile($successFile);
//if you want to delete the file from the server after emailing: unlink($newfile);
}
?>
I am working on a simple document management system for a site - the user can upload around 20 different file types and the docs are renamed then stored in a folder above www, an entry is created in a docs table to capture meta data entered by the user and the item is then retrieved via another php file so the stored location for the files are hidden from the user.
When a user clicks to download a file using a simple a href it calls, for example, "view.php?doc=image.jpg" - when they do this currently the file opens in the browser so a jpg opens a window with pages of "wingdings" like characters etc.
I would like to be able to force a open/save dialogue box so the user decides what to do and my app doesn't try to open in the browser window with the above results.
From a previous posting I found I know I cannot pass the mime type in the "a href" tag so what other options do I have? Could I put header information into the below view.php file, for example?
$_file = $_GET['doc'];
$filename = './dir/'.$_file;
if (file_exists($filename)) {
echo file_get_contents('./dir/'.$_file);
} else {
echo "The file $_file does not exist";
}
;
You could use get_headers() to get the MIME type header of the desired file, and then use header() to output those headers into the file you're showing.
Alternatively, to simply force downloads, this:
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");
Should do it.
I have a list of data compiled from a mysql recordset when I click a button on one of my pages. The data is stored in a variable $list.
It's a site activity log, and the button is a backup button.
Is there any way that I could make it open a SAVE AS dialogue box so I can save that data to a text file on my local comp?
when you click your "back up" button, you should get the user to a new script: this script should take the $list variable from the DB again and format it into a text file, then in order to make it available to the user's browser as a downloadable file, you should use headers (look at http://php.net/manual/en/function.header.php) like this:
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
In this case this is a pdf file (example is from the above link). Changing the content-type to the proper mime-type ("Content-Type: text/plain" for example) and setting the right file name, all that you echo will be sent to the browser as an attached file.
If any question, ask :)
after generate that file just set the physical path of that file and throw header so it will be download at your local system
Cheers
I have to allow a user to download after he has submitted his USER data.
I've created three pages,
will display files available for download(catalogue_downloads.html)
will take in USER data (form_collecting.php)
will take user data validate it send it to an email address and redirect to downloads page (mail.php)
The schema is so catalogue_downloads.html->form_collecting.php->mail.php->catalogue_downloads.html
I am able to redirect to catalogue_downloads but how can I make the user download the file he requested via PHP
Thank you
Regards
Vinoth
http://php.net/manual/en/function.readfile.php read the first part (forcing a download), you can read a file and then sending it to the user via the headers. Thus you don't have to give away your file structure (and perhaps even letting the file outside your website's root/public_html).
You can't feed the user multiple files, so unless you compress them server side in a single archive you have to show him the links to the files.
However, you're not limited to a link to the actual file, you can link to a "dowloader page" which feeds the user a single file when called so unauthorized users can't access the files (see PENDO's answer on how to do that).
you can user below code if needed..
$root = $_SERVER['DOCUMENT_ROOT']; $site = '';
$folder = "path where you want to store downloaded files";
$fullPath = $root.$folder.'/'.$_REQUEST['filenm'];
//$_REQUEST['filenm'] = file name which you want to download.
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower(html);
header("Content-type: application/".$ext);
header("Content-Transfer-Encoding: Binary");
header("Content-Disposition: attachment;filename=\"".$path_parts["basename"]."\"");
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
} } fclose ($fd); exit;
Thanks.
Here is the deal:
When redirecting from catalogue_downloads.html to form_collecting.php, give your catalog a unique ID and post it to form_collecting.php. Keep a hidden input field in your form which will keep the previously posted catalog ID. When the form is posted and validated start the process of mail.php. When mail is successful, read the catalog ID and redirect your user to the catalogue_downloads.html.
Hope this will help you out.
Regards