How to hide directory while giving directory Link? - php

I have build a laravel application where I have some files on public/files directory. if I give this link to others such as download Link, they have chance to know my directory ..
Suppose the link i have to give download link as
www.abc.com/files/45454553535.zip
But i don't want to let Users know that it's there in files directory. So How Do i hide the directory?

Keep your files in the storage directory. That way you can serve the file to the users through code.
Try to follow the documentation: https://laravel.com/docs/5.4/filesystem

I don't know whether this would work or not but giving you an idea. Create a php file use like this:
header('Content-Type: application/zip');
$a=file_get_contents(file.zip)
echo $a;
From this user will not know from where the contents are fetched.

Try this.
public function getDownload()
{
$filename='45454553535.zip'
$file= public_path(). "/files/".$filename;
$headers = array(
'Content-Type: application/zip',
);
return Response::download($file, $filename, $headers);
}
".files/45454553535.zip"will not work as you have to give full physical path.
Update 20/05/2016
Laravel 5, 5.1, 5.2 or 5.* users can use the following method instead of Response facade. However, my previous answer will work for both Laravel 4 or 5.
return response()->download($file, $filename, $headers);

You can just create a your controller and route.
Route::get('files/{filename}', [
'as' => 'file.get',
'uses' => 'FileController#get',
]);
Controller should check your proper directory. Try to keep your files in storage path, not public.
class FileController extends Controller
{
private $path;
public function __construct()
{
$path = storage_path()
. '/your-valid-directory/';
}
public function get($filename)
{
$file_path = $this->path
. filter_var($filename, FILTER_SANITIZE_STRING);
if (file_exists($file_path) && is_readable($file_path)) {
return response(file_get_contents($file_path), 200, [
'Content-Type: application/zip',
]);
} else {
abort(404);
}
}
}
Now you can get access to specific file by:
{{ route('file.get', ['filename' => '45454553535.zip') }}
This action generate link looks like: your-domain.com/files/45454553535.zip. :)
Anyway in my opinion - in the future just make file factory with specific headers, directories.
Good luck!

Related

Laravel: Refresh response()->file

In Laravel I use this route
Route::get('admin/showBill/{file}','Admin\FileController#showBill');
and this code
class FileController extends AuthController
{
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
return response()->file($path);
}
to display a pdf from my storage folder.
So if I have the pdf bill-1.pdf in my /storage/app/bills/ folder, then I can view it with the url
example-domain.com/admin/showBill/bill-1.pdf
The problem is that if I open that pdf with the browser, replace it, and refresh (F5) the page, then the old bill is shown. I guess its because its stored in the cache. Can I force Laravel to show the new replaced file?
I tried
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file) );
if(!\File::exists($path)) return back();
$path .= '?v='. time();
return response()->file($path);
}
But then Laravel tells me that this file does not exist. I am looking for a solution where I have not to rename the pdf file.
Are you sure you're replacing the right file?
If so, place this dd(). I've created an endpoint, response an empty pdf file - viewed it - replaced it with a content-filled pdf file and it works just fine when I replace it.
Edit: Also, you should validate the $file variable, using either a formrequest or validating in the controller.
public function showBill($file)
{
$path = storage_path('app/bills/' . basename($file));
if(!\File::exists($path)) {
dd("Quite possibly the problem is here, on the redirect back");
}
return response()->file($path);
}

Laravel File Downloaded from storage folder gets corrupted

I tried to download jpg/png image from storage folder its gets corrupted after downloaded.
This is my controller
public function download($filename) {
$headers = array(
'Content-Type: image/png',
);
return response()->download(storage_path() . '/'.$filename, 'final.png', $headers);
}
after open it look like this
Even i used core php script to download still iam facing same problem.
I believe that the Laravel framework might be introducing whitespace which might be ruining the header() function.
Use ob_end_clean() before your first header() call to remove any extra whitespace.
add this method before like this
ob_end_clean();
$headers = array(
'Content-Type: image/png',
);
return response()->download(storage_path() . '/'.$filename, 'final.png', $headers);
!enjoy
After Download .jpg,png,gif and .xlsx
Yes ! Its working;
I was reading this problem for 15 days and finally got the solution
Larabel 5.8 & PHP 7.3
public function download_user_photo($id) {
ob_end_clean();
$photo = UserGallery::find($id);
$path = 'storage/users/'.$photo->image_url;
enter code here
if (\File::exists($path)) {
return response()->download($path);
} else {
return redirect()->back()->with('danger', 'Image does not exist.');
}
}

Yii 2. Upload document outside public folder

I have a requirement to upload a document to server, since it is a personal one, they want it to be uploaded outside public folder. I know how to upload a file:
if ($model->load(Yii::$app->request->post())) {
$model->document = UploadedFile::getInstance($model, 'document');
if ($model->upload() !== false) {
$model->save();
}
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
But how do I read it since a Url will not be able to access it? I was planning to create an action to get the file but not sure if Yii has something ready for this case?
Yes Yii can send file output, but you still have to create your own action.
Lets assume following code in siteController Specific to image output, You can use same way to output other files.
public function actionImage($image_path) {
Yii::$app->getResponse()->sendFile(Yii::getAlias('#image_uploads') . $image_path);
}
now image src will be something like
<img src="/site/image?image_path=/posts/1.png" /> or equivalent to the real application url routes
So basic function to send file output by Yii2 is
Yii::$app->getResponse()->sendFile();
Located Under
\yii\web\Response.php

Laravel Response::download not working and pdf file not downloaded when clicked button

I'm trying to achieve a link in a menu bar, such that when a user clicks on the link, a pdf file will be downloaded automatically, and it should not navigate to other pages.
Inside my main.blade.php, consists of a menu bar, I have this link:
Help
where $_SERVER['SERVER_NAME'] is localhost.
Inside my routes.php:
Route::get('/download', array('uses'=>'MainController#getDownloadHelp'));
Inside my controller called MainController:
public function getDownloadHelp()
{
$file= public_path(). "/public/download";
$filename = 'help.pdf';
$headers = array(
'Content-Type' => 'application/pdf',
);
return Response::download($file, $filename, $headers);
}
The PDF file is stored under /public/download/help.pdf
The problem I'm facing right now is, when I clicked the 'Help' link on the menu bar, it redirects me to localhost/download which is not what I wanted. And also, the pdf is not downloaded.
I really need some help here! Where and what did I went wrong?
You can try to use {{ URL::to('/download') }} instead of $_SERVER['SERVER_NAME']...
or in your blade
echo link_to('download', $title, $attributes = array(), $secure = null);
it will write all the <a></a> thing
for the path in the controller maybe you can remove the public in the path of the file like this
public_path() . '/download/';

Download files in laravel using Response::download

In Laravel application I'm trying to achieve a button inside view that can allow user to download file without navigating to any other view or route
Now I have two issues:
(1) below function throwing
The file "/public/download/info.pdf" does not exist
(2) Download button should not navigate user to anywhere and rather just download files on a same view, My current settings, routing a view to '/download'
Here is how Im trying to achieve:
Button:
<i class="icon-download-alt"> </i> Download Brochure
Route :
Route::get('/download', 'HomeController#getDownload');
Controller :
public function getDownload(){
//PDF file is stored under project/public/download/info.pdf
$file="./download/info.pdf";
return Response::download($file);
}
Try this.
public function getDownload()
{
//PDF file is stored under project/public/download/info.pdf
$file= public_path(). "/download/info.pdf";
$headers = array(
'Content-Type: application/pdf',
);
return Response::download($file, 'filename.pdf', $headers);
}
"./download/info.pdf"will not work as you have to give full physical path.
Update 20/05/2016
Laravel 5, 5.1, 5.2 or 5.* users can use the following method instead of Response facade. However, my previous answer will work for both Laravel 4 or 5. (the $header array structure change to associative array =>- the colon after 'Content-Type' was deleted - if we don't do those changes then headers will be added in wrong way: the name of header wil be number started from 0,1,...)
$headers = [
'Content-Type' => 'application/pdf',
];
return response()->download($file, 'filename.pdf', $headers);
File downloads are super simple in Laravel 5.
As #Ashwani mentioned Laravel 5 allows file downloads with response()->download() to return file for download. We no longer need to mess with any headers. To return a file we simply:
return response()->download(public_path('file_path/from_public_dir.pdf'));
from within the controller.
Reusable Download Route/Controller
Now let's make a reusable file download route and controller so we can server up any file in our public/files directory.
Create the controller:
php artisan make:controller --plain DownloadsController
Create the route in app/Http/routes.php:
Route::get('/download/{file}', 'DownloadsController#download');
Make download method in app/Http/Controllers/DownloadsController:
class DownloadsController extends Controller
{
public function download($file_name) {
$file_path = public_path('files/'.$file_name);
return response()->download($file_path);
}
}
Now simply drops some files in the public/files directory and you can server them up by linking to /download/filename.ext:
File Name // update to your own "filename.ext"
If you pulled in Laravel Collective's Html package you can use the Html facade:
{!! Html::link('download/filename.ext', 'File Name') !!}
In the accepted answer, for Laravel 4 the headers array is constructed incorrectly. Use:
$headers = array(
'Content-Type' => 'application/pdf',
);
Quite a few of these solutions suggest referencing the public_path() of the Laravel application in order to locate the file. Sometimes you'll want to control access to the file or offer real-time monitoring of the file. In this case, you'll want to keep the directory private and limit access by a method in a controller class. The following method should help with this:
public function show(Request $request, File $file) {
// Perform validation/authentication/auditing logic on the request
// Fire off any events or notifiations (if applicable)
return response()->download(storage_path('app/' . $file->location));
}
There are other paths that you could use as well, described on
Laravel's helper functions documentation
While using laravel 5 use this code as you don`t need headers.
return response()->download($pathToFile); .
If you are using Fileentry you can use below function for downloading.
// download file
public function download($fileId){
$entry = Fileentry::where('file_id', '=', $fileId)->firstOrFail();
$pathToFile=storage_path()."/app/".$entry->filename;
return response()->download($pathToFile);
}
HTML href link click:
<a ="{{ route('download',$name->file) }}"> Download </a>
In controller:
public function download($file){
$file_path = public_path('uploads/cv/'.$file);
return response()->download( $file_path);
}
In route:
Route::get('/download/{file}','Controller#download')->name('download');
I think that you can use
$file= public_path(). "/download/info.pdf";
$headers = array(
'Content-Type: ' . mime_content_type( $file ),
);
With this you be sure that is a pdf.
// Try this to download any file. laravel 5.*
// you need to use facade "use Illuminate\Http\Response;"
public function getDownload()
{
//PDF file is stored under project/public/download/info.pdf
$file= public_path(). "/download/info.pdf";
return response()->download($file);
}
HTML link click
<a class="download" href="{{route('project.download',$post->id)}}">DOWNLOAD</a>
// Route
Route::group(['middleware'=>['auth']], function(){
Route::get('file-download/{id}', 'PostController#downloadproject')->name('project.download');
});
public function downloadproject($id) {
$book_cover = Post::where('id', $id)->firstOrFail();
$path = public_path(). '/storage/uploads/zip/'. $book_cover->zip;
return response()->download($path, $book_cover
->original_filename, ['Content-Type' => $book_cover->mime]);
}
This is html part
<a href="{{route('download',$details->report_id)}}" type="button" class="btn btn-primary download" data-report_id="{{$details->report_id}}" >Download</a>
This is Route :
Route::get('/download/{id}', 'users\UserController#getDownload')->name('download')->middleware('auth');
This is function :
public function getDownload(Request $request,$id)
{
$file= public_path(). "/pdf/"; //path of your directory
$headers = array(
'Content-Type: application/pdf',
);
return Response::download($file.$pdfName, 'filename.pdf', $headers);
}
you can use simply inside your controller:
return response()->download($filePath);
Happy coding :)
If you want to use the JavaScript download functionality then you can also do
<a onclick="window.open('info.pdf) class="btn btn-large pull-right"><i class="icon-download-alt"> </i> Download Brochure </a>
Also remember to paste the info.pdf file in your public directory of your project

Categories