Laravel protect audio file from direct url and show on blade view - laravel

I have a form with uploading audio mp3.
I need to protect these audio files from direct access from url, accessible only logged users.
Added a new storage disk in > filesystem.php
'audio' => [
'driver' => 'local',
'root' => storage_path('app/private/audio/'),
],
Added a new route in > web.php
Route::get('/private/audio/{audio}', [AudioController::class, 'index']);
AudioController
public function __construct()
{
$this->middleware('auth');
}
public function index($audio)
{
$path = "/private/audio/{$audio}";
if(Storage::exists($path)) {
return Storage::download($path);
}
abort(401);
}
Now if i get on follow url, my audio will download only for logged users, so works fine.
https://example.com/private/audio/my_audio_file.mp3
So how can I access to audio file in a blade view for logged users only.
#foreach($files as $file)
<audio preload="none" src="{{ asset('audio/private/') }}/{{ $file->file_name }}.mp3" controlslist="nodownload" type="audio/mp3">
</audio>
#endoforeach
Is there a way for get this?

It works fine after doing the optimize command:
php artisan optimize

#foreach($files as $file)
#if(Auth::check())
<audio preload="none" src="{{ asset('audio/private/') }}/{{ $file->file_name }}.mp3" controlslist="nodownload" type="audio/mp3"></audio>
#else
Login to access audio
#endif
#endforeach

Related

How to display file in laravel-8

I can upload file in database
and it is stored in my upload files.
Now I want to display it in in my show.blade.php, so I did this, but it is not working.
<iframe src="/storage/uploads/{{ $file->file_path }}" width="400" height="400"></iframe>
as result I got this not found in show.blade.php
So how can I display it? This is my FileController.php
class FileUpload extends Controller
{
public function createForm(){
return view('file-upload');
}
public function fileUpload(Request $req){
$req->validate([
'file' => 'required'
]);
$fileModel = new File;
if($req->file()) {
$fileName = time().'_'.$req->file->getClientOriginalName();
$filePath = $req->file('file')->storeAs('uploads', $fileName, 'public');
$fileModel->name = time().'_'.$req->file->getClientOriginalName();
$fileModel->file_path = '/storage/' . $filePath;
$fileModel->save();
return back()
->with('success','File has been uploaded.')
->with('file', $fileName);
}
}
public function show(File $file)
{
// $news=News::find($id);
return view('show',compact('file'));
}
}
this is web.php
Route::get('/upload-file', [FileUpload::class, 'createForm']);
Route::post('/upload-file', [FileUpload::class, 'fileUpload'])->name('fileUpload');
Route::get('/uploadshow', [FileUpload::class, 'show']);
Thanks
Screen short of ifream
You may use the URL method to get the URL for a given file. If you are using the local driver, this will typically just prepend /storage to the given path and return a relative URL to the file. If you are using the s3 driver, the fully qualified remote URL will be returned:
<iframe src="{{ URL::asset('storage/uploads/'.$file->file_path}}"width="400" height="400"></iframe>
You need to put proper path in iframe using asset()
<iframe src="{{ asset('storage/app/public/uploads/') }}/{{ $file->file_path }}" width="400" height="400"></iframe>
Your route uploadshow should have parameter fileId like this uploadshow/{fileId}.
Then in your show function will be show($fileID).
$file = File:find($fileID)
In your frame src,
asset($file->file_path)

laravel local storage 404 error on images

I have made a youtube style website, some people may click the video to be private, I keep these videos in storage/app/vidoes/{channelname}, the public images and videos I have working not a problem but local storage I am having a problem with, any ideas?
just getting a 404 on the thumbnails
thanks
view
<img src="{{ route('home.image', ['file_path' => 'videos/' . $video->channel_name . '/thumbnails/' . $video->video_thumbnail_name]) }}" alt="" class="img-responsive">
route
Route::get('{file_path}', [
'uses' => 'HomeController#getImage',
'as' => 'home.image'
]);
controller
public function getImage($filepath)
{
$fileContents = \Storage::disk('local')->get($filepath);
$response = \Response::make($fileContents, 200);
$response->header('Content-Type', "image/jpg");
return $response;
}
Laravel 5.8 local storage working for images
view
<img class="home-video" src="{{ route('getImage', ['thumbnail' => $video->video_thumbnail_name, 'channel_name' => $video->channel_name]) }}" alt="" >
Route
Route::get('get-image/{channel_name}/{thumbnail}','HomeController#getImage')->name('getImage');
Controller
public function getImage($channel_name,$thumbnail)
{
$fileContents = \Storage::disk('local')->get("videos/$channel_name/thumbnails/$thumbnail");
return \Image::make($fileContents)->response();
}
see how the thumbnail is important for me, I was passing the thumbnail name eg photo.jpg if you are using route model binding you would want to pass the id of the image, hope this saves someone a few hours

Display Images From Storage Folder in View

When I upload images to a storage folder in my localhost, it works fine. However, when I move my Laravel 5.7 project to shared hosting the images don't appear, and I don't know why.
Thank you for your help.
Blade
#foreach ($data as $user)
#foreach(json_decode($user->name, true) as $images)
#endforeach
#endforeach
<!-- Wrapper for slides -->
<div class="carousel-inner">
#foreach ($data as $user)
#foreach(json_decode($user->name, true) as $images)
<div class="item">
<img src="{{ asset('/slider/images') }}/{{$images}}" alt="Los Angeles" style="width:100%;">
</div>
#endforeach
#endforeach
</div>
Controller
<?php
if ($request->hasfile('image')) {
foreach ($request->file('image') as $image) {
$name = $image->getClientOriginalName();
$image->move(storage_path() . '/slider/images/', $name);
$data[] = $name;
}
$query = DB::table('slider')->insert([
['title' => 'lorem', 'alt' => 'lorem', 'name' => json_encode($data)],
]);
return "good";
} else {
return "null";
}
https://stackoverflow.com/a/50771337/3240068
Your shared hosting server may or may not allow symlinks. If you run the command and it still does not work, then you have two options, basically.
1) Upload / move / copy images from storage to public;
2) https://laravel.com/docs/5.7/responses#file-downloads
Create a route and controller that reads and returns images from storage. This is not tested, so do some proof-reading and research, but it should go something like this:
// Route
Route::get('storage-asset/{$path}', 'App\Http\SomeController#getStorageAsset');
// Controller
public function getStorageAsset($path)
{
if (File::exists(storage_path($path)) {
return response()->file(storage_path($path));
}
// If file not found.
return abort(404)
}
Please try login using ssh and run
php artisan storage:link
or create .htaccess to your root laravel folder and add this code below.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
and make sure you have proper permission to your storage folder.
that could probably helps.
You need to create a file (e.g, link.php) inside the public folder and declare the codes below.
make sure to declare your path as is in your app.
<?php
symlink('../public_html/storage/app/public', '../public_html/public/storage');
then, you can visit your-domain.com/link.php, and that's it. done

Displaying laravel stored images on shared hosting

I have successfully deployed my first laravel application on a live server. Everything looks great except the fact that I am unable to display the images that are being uploaded to the
/myproject_src/storage/app/public/myfolder1 folder.
Here is my folder hierarchy on HostGator:
/myproject_src/
Here are all the laravel source files (except the public folder)
/public_html/mydomain.com/
Here goes all my contents of the public directory
I am storing the file path into the database in the following manner:
public/myfolder1/FxEj1V1neYrc7CVUYjlcYZCUf4YnC84Z3cwaMjVX.png
This path is associated with the image that has been uploaded to storage/app/public/myfolder1/ this folder and is generated from store('public/myfolder1'); method of laravel.
What should I do in order to display the images properly in a img tag:
<img src="{{ how to point to the uploaded image here }}">
Well, you can create symbolic link using
php artisan storage:link
and access files using
<img src="{{ asset('public/myfolder1/image.jpg') }}" />
But sometime you can't create symbolic link if you're on shared hosting. You want to protect some files behind some access control logic, there is the alternative of having a special route that reads and serves the image. For example.
Route::get('storage/{filename}', function ($filename)
{
$path = storage_path($filename);
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
Now you can access your files like this.
http://example.com/storage/public/myfolder1/image.jpg
<img src="{{ asset('storage/public/myfolder1/image.jpg') }} />
Note: I'd suggest to not store paths in the db for flexibility. Please just store file name and do the following thing in the code.
Route::get('storage/{filename}', function ($filename)
{
// Add folder path here instead of storing in the database.
$path = storage_path('public/myfolder1' . $filename);
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
and access it using
http://example.com/storage/image.jpg
Hope that helps :)
The simple answer here is run php artisan storage:link command manually
first, delete the storage folder inside your public folder
then add this code to the top of the web.php file.
Artisan::call('storage:link');
Hope this will help you.
An easy way that works could be running php artisan storage:link in your shared hosting ssh terminal. Then simply change the url for the public driver in filesystem.php
'disks' => [
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/public/storage',
'visibility' => 'public',
],
]

Laravel5.2 delete doesn't work

I developed website with CRUD on products table .this is the structure of the table.
Create and update works fine But delete not work.
This is the form in blade to delete product
{{ Form::open(array('url' => 'admin/products/' . $product->id, 'class' => 'pull-right')) }}
{{ Form::hidden('_method', 'DELETE') }}
{{ Form::submit('Delete ', array('class' => 'btn btn-warning')) }}
{{ Form::close() }}
And this the destroy function in controller
public function destroy($id)
{
$product = Product::find($id);
$product->delete();
// Product::destroy($id);
return redirect('admin/products')->with('message', 'Successfully deleted the product!');
}
And This is my routes
Route::group(['middleware' =>'App\Http\Middleware\AdminMiddleware'], function () {
//resource
Route::resource('admin/products','AdminFront');
});
When I click delete button it enter the destroy function and dd($id) correct
But when write
$product = Product::find($id);
$product->delete();
Or
Product::destroy($id);
I get this error
The localhost page isn’t working
localhost is currently unable to handle this request.
This error tired me . I developed delete fun with resource API in another table and work fine.I don't know are the problem in the db or where. please any one help me ,
What does your routes.php look like?
You may need to include the resource route in routes.php.
Route::resource('admin/products/', 'TheNameOfYourController');
But make sure the route is protected either in the controller or routes.php.
Here is somewhat the same setup you have:
https://github.com/jeremykenedy/laravel-material-design/blob/master/app/Http/routes.php LINE 119
https://github.com/jeremykenedy/laravel-material-design/blob/master/app/Http/Controllers/UsersManagementController.php LINES 369-376
https://github.com/jeremykenedy/laravel-material-design/blob/master/resources/views/admin/edit-user.blade.php LINES 243-246
Cheers!

Resources