Yii - View protected PDF files - php

In my application, there are some PDF files that users upload to server. These are private files and they cannot have global visibility.
I'm trying to upload these files to a protected directory (/protected/uploads, for example). The users must be able to view these files, but they must not be visible by the client browser.
Something like an "internal view" of my application.
How can I do that?
If I use the "assets" directory the files will be global visible, right?
Thanks!

You need to send the right header and perform a readfile such as:
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="yourPDF.pdf"');
header('Content-Length: ' . filesize($filename));
readfile($filename);
This will open the file in the browser as you requested and will prevent the user to grab it directly.

What you are after is a method on the request component, sendFile. It's briefly described here: http://www.yiiframework.com/doc/api/1.1/CHttpRequest#redirect-detail
Usage would be:
Yii::app()->request->sendFile($filename, $content);
$filename will be what you want the file users download to be called

Related

Php header() User Agent Change

$file_name = $_GET['title'];
$file_url = $_GET['url'] . $file_name;
header('Content-Type: video/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
I'm using this code to download files in my site fetching from another websites.
It works if my url looks like:-
https://www.example.com/video_download.php?title=video.mp4&url=http://googlevideo.com/video/download/223689/289048
(example)
So, it starts downloading by fetching the video file from http://www.googlevideo.com/video/play/221589 to my site.
But my problem is that the file can be accessed if the person uses a PC.
Can I change the User Agent by using header()?
Is it possible?
So if I change the user agent into a PC user agent, so it can be downloaded from a mobile!
I'm sorry, but the User Agent has nothing to do with readfile() function. Readfile() will just throw the raw file input into your browser. Useful for e.g. rendering images through PHP to the client without having to expose the real file name.
Indeed, it is possible to render video to the client with readfile(), but using a HTML5 video tag will dramatically improve performance. This will also provide better mobile support.
Hope this helps you,
You can use stream_compy_to_stream
$video = fopen($file_url);
$file = fopen('videos/' . $title . '.mp4', 'w');
stream_copy_to_stream($video, $file); //copy it to the file
fclose($video);
fclose($file);
I wrote a class for downloading youtube video files. you can find it here.

Dynamically display pdf in iframe

I on a system where site owners can load securely pdf documents into a document bank based on their category, ei: meeting related documents, ebooks, reports, etc. The system loads them into a directory based on the category in which they were assigned at the time of the upload. This means not all pdf documents will be in the same sub-directory as each category has its own sub-directory in which it stores its files. When the site owner, from the frontend, views a list of all the documents in that category and clicks on the document, currently it opens a modal that allows them to view the file data and download the file; but it doesn't allow them to view the pdf file prior to downloading or simply to print instead of downloading. What I am trying to do is write a php code that will dynamically pull the correct pdf and display it in an iframe on the corresponding download page for the owners to view. These are the various ways I've attempted this, each one failed.
MODIFIED Version 1.0 failed:
<?php
$file = 'docstation/$parent_type/$parent_id'/$id;
$filename = '$file_name'; /* Note: Always use .pdf at the end. */
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $file_name . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);
?>
EXPLANATION: The real path is docstation/com_docstation/97/...
1-> 'docstation' being a directory that sits on the root of their site
2-> '$parent_type' = 'com_docstation' referenced in the sql table as the method of upload (another method is via an attachment to an article, so i'd need this to be dynamic too)
3-> 'parent_id' = '97' the id of the category which would also equal the name of the sub_directory the file is actually stored in, aka '97'
4-> 'id' = being the id of the document
I thought fore sure this would work but it didn't
MODIFIED Version 1.1 failed:
<?php
echo "<iframe src=\"http://docs.google.com/gview?url=docstation/$parent_type/$parent_id'/$id\" width=\"100%\" style=\"height:100%\"></iframe>";
?>
This didn't either. I'm open to suggestions. All I know is that I can't put a real path in there because the path will vary from one document to another based on the method of upload and the category assigned.
Anyone got any suggestions?
Dorothy

Link to a PDF in html, the file has no extension, but I know it is pdf how to make it open appropriately

First post. I'm working on a project for a client where they have pdf files uploaded to a file structure (LAMP Stack) but the files have no extensions on them. Under the assumption that those files have to be PDF how would I get the browsers to understand that, and open them accordingly? Obviously with adding the file extensions this would suddenly work but I can't change the way their system works, it would result in too many changes and they are on a tight deadline. As for saving a temporary copy somewhere, I could do that, but I was hoping for a better solution. Is there a way to suggest to the browsers that they open a file a certain way?
Any thoughts guys/gals?
You just set the application type and file name in the headers, like so:
// This points to the file in question, note that it doesn't
// care whether it has an extension on the name or not.
$filePathOnDisk = '/path/to/your/pdffile';
// You can make this whatever you like, it doesn't have to
// be the same as the file name on the disk! This is the name of the file your end
// user will see when they are asked if they want to save. open, etc in the browser.
$fileName = 'file.pdf';
$data = file_get_contents($filePathOnDisk);
header("Content-type: application/pdf");
header("Content-disposition: attachment;filename=$fileName");
echo $data;
See PHP: stream remote pdf to client browser and Proper MIME media type for PDF files for reference as well.
Tested
You can use the following which will prompt the user to save the (PDF) file on their computer.
Notice the different file names.
One is the file that will be uploaded/prompted to the user download_example.pdf, while the other is the file without an extension as set in readfile('example');
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="download_example.pdf"');
readfile('example');
?>

Get output file with a .pdf extension in FPDF

This question is for those who have used PHP library FPDF (http://www.fpdf.org ) to generate PDF documents using PHP. I am generating a PDF file using the php file 'my_file.php'. I want users to be able to download that PDF file. But in the browser the see the file in the address bar as ..somepath..../my_file.php . I want them to see it as a file with .pdf extension. Any idea how this can be done ?
when you create the object and then try to make output like this
$filePath = "files/cache/myPdf.pdf";
$pdf=new FPDF('p');
...
$pdf->Output($filePath,'I');
you can change and send the file name
To force download:
$pdf->Output('D'); //Force download and set filename as 'doc.pdf'
or setting your own filename:
$pdf->Output('MyFilename.pdf','D');
Your browser shall not open another tab whit yourpath/my_file.php
You can't change the browser address bar, but you can change the address on your server. For example if you're using Apache, there's mod_rewrite which allows you to do such things.
If your problem is that when downloading the file, the browser wants to save it as .php, you could use those headers to force the download and a filename.
header('Content-Type: application/octet-stream');
header('Content-Length: ' . FILESIZE_HERE);
header('Content-Disposition: attachment; filename=' . FILENAME.pdf_HERE);

How to force a file to download in PHP

I have list of images and I want a "Download" link along with every image so that user can download the image.
so can someone guide me How to Provide Download link for any file in php?
EDIT
I want a download panel to be displayed on clicking the download link I dont want to navigate to image to be displayed on the browser
If you want to force a download, you can use something like the following:
<?php
// Fetch the file info.
$filePath = '/path/to/file/on/disk.jpg';
if(file_exists($filePath)) {
$fileName = basename($filePath);
$fileSize = filesize($filePath);
// Output headers.
header("Cache-Control: private");
header("Content-Type: application/stream");
header("Content-Length: ".$fileSize);
header("Content-Disposition: attachment; filename=".$fileName);
// Output file.
readfile ($filePath);
exit();
}
else {
die('The provided file path is not valid.');
}
?>
If you simply link to this script using a normal link the file will be downloaded.
Incidentally, the code snippet above needs to be executed at the start of a page (before any headers or HTML output had occurred.) Also take care if you decide to create a function based around this for downloading arbitrary files - you'll need to ensure that you prevent directory traversal (realpath is handy), only permit downloads from within a defined area, etc. if you're accepting input from a $_GET or $_POST.
In HTML5 download attribute of <a> tag can be used:
echo '<a href="path/to/file" download>Download</a>';
This attribute is only used if the href attribute is set.
There are no restrictions on allowed values, and the browser will
automatically detect the correct file extension and add it to the file
(.img, .pdf, .txt, .html, etc.).
Read more here.
The solution is easier that you think ;) Simple use:
header('Content-Disposition: attachment');
And that's all. Facebook for example does the same.
You can do this in .htaccess and specify for different file extensions. It's sometimes easier to do this than hard-coding into the application.
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
By the way, you might need to clear browser cache before it works correctly.

Categories