I am having problem creating a download link to download files via a Mobile App from Laravel Storage folder.
I did something like $link = Response::Download(storage_path()./file/example.png) but to no avail.
I moved the file to the public folder and used http://domain.com/file/example.png and asset('file/example.png') but to no avail.
I am getting 404 NOT FOUND ERROR
How do I solve this?
Take a look at the Laravel Helpers documentation: http://laravel.com/docs/4.2/helpers
If you want a link to your asset, you can do it like this:
$download_link = link_to_asset('file/example.png');
Edit
If the above method does not work for you, then you can implement a fairly simple Download route in app/routes.php which looks like this:
Note this example assumes your files are located in app/storage/file/ location
// Download Route
Route::get('download/{filename}', function($filename)
{
// Check if file exists in app/storage/file folder
$file_path = storage_path() .'/file/'. $filename;
if (file_exists($file_path))
{
// Send Download
return Response::download($file_path, $filename, [
'Content-Length: '. filesize($file_path)
]);
}
else
{
// Error
exit('Requested file does not exist on our server!');
}
})
->where('filename', '[A-Za-z0-9\-\_\.]+');
Usage: http://your-domain.com/download/example.png
This will look for a file in: app/storage/file/example.png (if it exists, send the file to browser/client, else it will show error message).
P.S. '[A-Za-z0-9\-\_\.]+ this regular expression ensures user can only request files with name containing A-Z or a-z (letters), 0-9 (numbers), - or _ or . (symbols). Everything else is discarded/ignored. This is a safety / security measure....
Updating answer for Laravel 5.0 and above:
<a href={{ asset('file/thing.png') }}>Thing</a>
You do not need any route or controller.Just give it to anchor tag.
<a href="{{URL::to('/')}}/file/example.png" target="_blank">
<button class="btn"><i class="fa fa-download"></i> Download File</button>
</a>
Related
Consider the case where a user uploaded his profile image and it was placed in the project as public/userprofileimage.jpg when the repository was at version 1.0.0.
The project was then pulled from GitHub, changed, or new code was added, and it was pushed to the repository, becoming version 2.0.0.
How can I add the latest uploaded photos to the repository each time a user uploads something?
Will the user-uploaded picture be in 2.0.0?
or the image will be lost
What should I do with the user-uploaded images if that's the case so they don't get lost in version control?
if($request->hasFile('image1') && $request->hasFile('image2') && $request->hasFile('image3') && $request->hasFile('image4')){
$formFields['media'] =
$request->file('image1')->store('postUploads','public') . ','
. $request->file('image2')->store('postUploads','public') . ','
. $request->file('image3')->store('postUploads','public') . ','
. $request->file('image4')->store('postUploads','public');
}
and did that
php artisan storage:link
l retrieve the image like that
<img src="{{asset('storage/' . $image)}}" class="md:w-48 m-2 rounded" alt="">
is that the right way?
thanks
A better approach
use Illuminate\Support\Facades\Validator;
public function store(Request $request){
$validate = Validator::make($request->all(), [
$request->file('image1') => 'required|mimes:jpg,png,jpeg',
$request->file('image2') => 'required|mimes:jpg,png,jpeg',
$request->file('image3') => 'required|mimes:jpg,png,jpeg',
$request->file('image4') => 'required|mimes:jpg,png,jpeg',
]);
if( $validate->fails() ){
return response($validate->errors(), 400);
}
//anything below here means validation passed. You can then store your images
$path1 = $request->file('image1')->store('profile_pictures','public');
$path2 = $request->file('image2')->store('profile_pictures','public');
$path3 = $request->file('image3')->store('profile_pictures','public');
$path4 = $request->file('image4')->store('profile_pictures','public');
}
Note that this can even be further simplified by saving your images to an array. I did not use that approach as I am not sure whether all the images are profile images or will be used differently.
Your images will be stored in /storage/profile_pictures and Laravel will automatically generate an image name for you.
On your view you can call the images using the asset helper as below
<img src="{{ asset($path1) }}"/>
This is assuming you are sending the image paths individually, which also can be simplified based on your application. Hope this give you an idea.
I'm working on a web application using Laravel 5.8, I'm new to Laravel framework. I would like to display PDF documents on the browser when users click on some buttons. I will allow authenticated users to "View" and "Download" the PDF documents.
I have created a Controller and a Route to allow displaying of the documents. I'm however stuck because I have a lot of documents and I don't know how to use a Laravel VIEW to display and download each document individually.
/* PDFController*/
public function view($id)
{
$file = storage_path('app/pdfs/') . $id . '.pdf';
if (file_exists($file)) {
$headers = [
'Content-Type' => 'application/pdf'
];
return response()->download($file, 'Test File', $headers, 'inline');
} else {
abort(404, 'File not found!');
}
}
}
/The Route/
Route::get('/preview-pdf/{id}', 'PDFController#view');
Mateus' answer does a good job describing how to setup your controller function to return the PDF file. I would do something like this in your /routes/web.php file:
Route::get('/show-pdf/{id}', function($id) {
$file = YourFileModel::find($id);
return response()->file(storage_path($file->path));
})->name('show-pdf');
The other part of your question is how to embed the PDF in your *.blade.php view template. For this, I recommend using PDFObject. This is a dead simple PDF viewer JavaScript package that makes embedding PDFs easy.
If you are using npm, you can run npm install pdfobject -S to install this package. Otherwise, you can serve it from a CDN, or host the script yourself. After including the script, you set it up like this:
HTML:
<div id="pdf-viewer"></div>
JS:
<script>
PDFObject.embed("{{ route('show-pdf', ['id' => 1]) }}", "#pdf-viewer");
</script>
And that's it — super simple! And, in my opinion, it provides a nicer UX for your users than navigating to a page that shows the PDF all by itself. I hope you find this helpful!
UPDATE:
After reading your comments on the other answer, I thought you might find this example particularly useful for what you are trying to do.
According to laravel docs:
The file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download.
All you need to do is pass the file path to the method:
return response()->file($pathToFile);
If you need custom headers:
return response()->file($pathToFile, $headers);
Route::get('/show-pdf/{id}', function($id) {
$file = YourFileModel::find($id);
return response()->file(storage_path($file->path));
})->name('show-pdf');
Or if file is in public folder
Route::get('/show-pdf', function($id='') {
return response()->file(public_path().'pathtofile.pdf');
})->name('show-pdf');
then show in page using
<embed src="{{ route('show-pdf') }}" type="text/pdf" >
I can't figure out how to get a database file attachment, to be downloaded with is real file name.
My model have many file attachements (many attachOne) and there is no problem to get link to them with
{{ model.myfile.filename }}
What I want to do is to get those files downloaded with their real file name.
I try to define an ajax event handler in my layout like so :
function onDonwload()
{
$path = post('path');
$name = post('name');
// Storage::exists('uploads/public/5ce/28c/3aa/5ce27c3aae590316657518.pdf'); => OK
// Storage::exists($path); =>OK
$path = storage_path().'/app/'. $path;
return Response::download( $path, $name);
}
and
<button data-request="onDonwload"
data-request-data="path: 'uploads/public/5ce/28c/3aa/5ce27c3aae590316657518.pdf', name: 'my real name">
Download
</button>
No missing file error, but get the browser to freeze with an alert that say "A webpage slow down your browser, what do you want to do?".
Did I miss an important point?
You should add separate page for downloading files, Ajax can not help you to download file ( may be it can but process is little complex and long)
create page with /file-download/:id here you can specify any url wit param :id and give it name file-download you can give any name you like for demo i used this name.
In that Page Html section will be Blank and in Page's code section add this code. here you can also check additional security check like user is logged in or not file is of related user or not. for now i am just checking file is related to particular Modal or not.
function onStart() {
$fileId = $this->param('id');
$file = \System\Models\File::find($fileId);
// for security please check attachment_type == your model with namespace
// only then lat use download file other wise user can download all the files by just passing id
if($file && $file->attachment_type == 'Backend\Models\User') { // here add your relation model name space for comparison
$file->output('attachment');
}
else {
echo "Unauthorised.";
}
exit();
}
Generating links, please replace page name with page you created.
<a href="{{ 'file-download'|page({'id': model.myfile.id}) }}" >{{ model.myfile.filename }}</a>
Now, when you click on link file should be downloaded with its original name, and for invalid file id it should show message Unauthorised..
if any doubts please comment.
I'm trying to make download button which take one file from database and download it. So far this is what I have and will appreciate some help.
My DownloadsController.php
class DownloadsController extends Controller
{
public function download($file_name) {
$file = DB::table('media')->where('status',1)->get();
$file_path = public_path('files/'.$file);
return response()->download($file_path);
}
}
My route
Route::get('/files/{file}', 'DownloadsController#download');
The button
{!! Html::link('files/{file}', 'Download Media') !!}
What I see on the link is http://example/files/{file}. How to place the file on the download link?
You would typically define your route in routes/web.php e.g.
https://laravel.com/docs/5.7/routing#named-routes
Route::get('file/{file}', 'Controller#method')->name('file-download');
This means on your button you need to at the correct link for the filename e.g.
{!! Html::link('files/filename.jpg', 'Download Media') !!}
Remember this needs to be a valid filename. Alternartively you can use the route helper by inserting the route name as above followed by the parameter of the route e.g route('file-download', 'filename.jpg').
Final button link would look as follows using the routing helper;
{!! Html::link(route('file-download', 'filename.jpg'), 'Download Media') !!}
So use is uploading a logo and it's path is stored in a database like this:
C:\xampp\htdocs\laravel\public\logo\1496912432.jpg
I am displaying the image like this:
<img class="images" id="image" src="{{$business->image}}" />
However I get this error:
Not allowed to load local resource: file:///C:/xampp/htdocs/laravel/public/logo/1496912432.jpg
How can this problem be solved?
//edit
Controller:
public function image(Request $request) {
if($request->hasFile('img'))
{
$image = Input::file('img');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('logo/' . $filename);
Image::make($image->getRealPath())->fit(303, 200)->save($path);
$file = $request->file('img');
$session = session()->get('key');
$update_image = Business::find($session);
$update_image->image = $path;
$update_image->save();
return ['url' => url('logo/' . $filename)];
}
Use Laravel file() to store files https://laravel.com/docs/5.4/requests#files
Store the $path to your db
$path = $request->photo->store('logo');
the $request->photo is depending on your input file attribute name. In your case, it should be $request->img.
the above code will create a folder (if not exist), namely "logo" and store to that folder with random string file name.
Also check your configuration for file, located at /config/filesystem.php. Default is set to public
Use asset function to get the full path from public folder
<img class="images" id="image" src="{{ asset($business->image }}" />
You can do in two ways
Best way is update url path when image saving save url path to db
$path = $request->photo->store('logo'); // in 5.4
The other way if you can't changes db url you can do some hack like this
$file = explode('/public/', $business->image);
echo asset($file[1]);
You want to store all files inside the web root. Because of cross-domain security, you cannot access the file:// domain/protocol from a http protcol. By using Laravel to store and retrieve, it will come from the same host.