How to return image in Laravel 6? - laravel

I have this code:
public function showImage($id) {
$item = File::find($id);
return response()->file($item->file_name_and_path);
}
$item->file_name_and_path contains the following:
files/2020/04/29/myfile.jpeg
Now I always get a FileNotFoundException.
The image file is on local driver in this path:
{laravel root}/storage/app/files/2020/04/29/myfile.jpeg
How can I get the correct local path or simply return the image file with image HTTP headers?

You could use the Storage facade for this:
use Illuminate\Support\Facades\Storage;
public function showImage($id) {
$item = File::find($id);
return Storage::response($item->file_name_and_path);
}
As you can see here, it will add the following headers to the response:
'Content-Type'
'Content-Length'
'Content-Disposition'

Related

Laravel unlink method

can someone tell me how to unlink image from public path when product is deleted.
My current code which does not work:
public function destroy($id)
{
$product = Product::findOrFail($id);
$image_path = '/uploads/products/' . $product->image;
if(file_exists($image_path)){
unlink($image_path);
}
$product->delete();
}
Also tried:
$product = Product::findOrFail($id);
if(file_exists($product->image)){
unlink($product->image);
}
$product->delete();
Also I am using accessor so my $product->image is returning:
"http://myeshop.local/uploads/products/1593902362bluesocksupd.jpg"
Here is accessor code:
public function getImageAttribute($image){
return asset($image);
}
use model deleted event
//Product Model
protected static function boot()
{
parent::boot();
static::deleted(function($product){
// getOriginal skip accessor
$image = public_path('uploads/products/' . $product->getOriginal('image'));
if(file_exists($image)) {
unlink($image);
}
});
}
unlink($path) is a PHP function. It will delete a file located at a local path. According to your question the value of $product->image is the complete URL to the image. If it is then the following is true:
$product = Product::findOrFail($id);
$image_path = '/uploads/products/' . $product->image;
// $image_path = '/uploads/products/http://myeshop.local/uploads/products/1593902362bluesocksupd.jpg'
// and it needs to point to '/PATH/TO/LARAVEL/uploads/products/1593902362bluesocksupd.jpg'
// the following file_exists() will return false
if(file_exists($image_path)){
unlink($image_path); // so you never get here
}
There are some quick and dirty ways to fix this, but the best thing to do is to have the $product->image property point to just the name of the file. Then in your view apply the file name to the /uploads/products/ directory on the web server.
Doing this will allow you to apply the /uploads/products/ local path and have a better time finding the file you want to delete. I'm assuming the uploads directory is in your Laravel public directory so you'd want to do something like this:
// $product->image must point to the filename only: 1593902362bluesocksupd.jpg
// The file_exists should evaluate to true and unlink() will work.
$image_path = public_path('uploads/products/' . $product->image);
if(file_exists($image_path)){
unlink($image_path);
}
In your Blade template view you'd need to show the product image using something like this:
<img src="{{ url('/uploads/products/' . $product->image) }}" />
Storing a complete URL in your database doesn't scale well if you wanted to develop another website or reuse this code on another project. This way you can let Laravel manage where the URL or local file system is.
You could use PHP's unlink() method.
But if you want to do it the Laravel way, use the Storage::delete method instead :
use Illuminate\Support\Facades\Storage;
public function destroy($id)
{
$product = Product::findOrFail($id);
$image_path = public_path('uploads/products/' . $product->image);
if(file_exists($image_path)){
Storage::delete($image_path);
}
$product->delete();
}

How to serve the data returned from laravel Storage::disk('private')->get($file) as PDF

My question is about the problem in link below :
Understanding file storage and protecting contents Laravel 5
I need to use the same method mentioned in above example but instead of an image I need to provide a download link for PDF file or a link to open PDF file in browser and I can't do that because, as mentioned in above example's comments The Storage::disk('private')->get($file) returns the CONTENT of the file NOT the URL.
Please tell me how can I convert the row data (content of file) to a file and provide the link for the users inside the view.
You should follow the below steps:
I have store pdf file into storage/app/pdf
In controller:
public function __construct()
{
$this->middleware('auth');
}
public function index(Request $request, $file)
{
$file = storage_path('app/pdf/') . $file . '.pdf';
if (file_exists($file)) {
$headers = [
'Content-Type' => 'application/pdf'
];
return response()->file($file, $headers);
} else {
abort(404, 'File not found!');
}
}
if laravel below 5.2:
Add use Response; above controller class in the controller.
public function index(Request $request, $file)
{
$file = storage_path('app/pdf/') . $file . '.pdf';
return Response::make(file_get_contents($file), 200, [ 'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$file.'"'
]);
}
In web.php
Route::get('/preview-pdf/{file}', 'Yourcontroller#index');
In the blade view:
PDf
According to the Laravel documentation you can simply use the download method on the Storage facade.
From your controller, return the result of the command.
return Storage::disk('private')->download($file);

Laravel/Lumen file response

I need to stream file content (such as images and other mime types) from a Lumen resource server to a Laravel client server. I know in Laravel I can use:
$headers = ['Content-Type' => 'image/png'];
$path = storage_path('/mnt/somestorage/example.png')
return response()->file($path, $headers);
However, the file method is absent in Laravel\Lumen\Http\ResponseFactory.
Any suggestions are very welcome.
In Lumen you can use Symfony's BinaryFileResponse.
use Symfony\Component\HttpFoundation\BinaryFileResponse
$type = 'image/png';
$headers = ['Content-Type' => $type];
$path = '/path/to/you/your/file.png';
$response = new BinaryFileResponse($path, 200 , $headers);
return $response;
You can find the documentation here.
There is a function in Lumen:
https://lumen.laravel.com/docs/8.x/responses#file-downloads
<?php
namespace App\Http\Controllers;
use App\Models\Attachment;
use Illuminate\Http\Request;
class AttachmentController extends AbstractController
{
/**
* Downloads related document by id
*/
public function attachment(Request $request)
{
$path = "path/to/file.pdf";
return response()->download($path);
}
}

Laravel 5.3: delete image from storage

I have a method which deletes a product and image that belongs to it, but I can not delete the image.
Where am I going wrong with this?
public function deleteProduct($ids)
{
foreach ($ids as $id => $value) {
$product = Product::find($id);
$productImage = $product->image_path;
if ($productImage) {
Storage::delete($productImage);
$product->destroy($id);
}
}
}
I have a symlink between storage and public folder.
Under storage images are located at e.g. - storage/app/public/images/products/4/image.png
Under public - public/storage/images/products/4/imagep.png
Image path is stored in database as - /storage/images/products/4/ACTCMRcYlWR8Bn3ZxoJ7bpiDJ7.png
I had to add remove '/storage' part of the path and prepend '/public'.
$productImage = str_replace('/storage', '', $product->image_path);
Storage::delete('/public' . $productImage);
If you added /storage part to the path you can use file system:
if (File::exists(public_path($image->path))) {
File::delete(public_path($image->path));
}
I would write something like this in my Model or helper and call it whenever I want:
public static function delete_file($path)
{
if (\Storage::disk('public')->exists($path))
\Storage::disk('public')->delete($path);
}

How to delete file from public folder in laravel 5.1

I want to delete a News from database and when I hit the delete button all data from database deleted but the image is remains in upload folder.
So, how do I this to work.
thanks
This is my function again but does not delete the image from images/news folder of public directory>
public function destroy($id) {
$news = News::findOrFail($id);
$image_path = app_path("images/news/{$news->photo}");
if (File::exists($image_path)) {
//File::delete($image_path);
unlink($image_path);
}
$news->delete();
return redirect('admin/dashboard')->with('message','خبر موفقانه حذف شد');
}
You could use PHP's unlink() method just as #Khan suggested.
But if you want to do it the Laravel way, use the File::delete() method instead.
// Delete a single file
File::delete($filename);
// Delete multiple files
File::delete($file1, $file2, $file3);
// Delete an array of files
$files = array($file1, $file2);
File::delete($files);
And don't forget to add at the top:
use Illuminate\Support\Facades\File;
Use the unlink function of php, just pass exact path to your file to unlink function :
unlink($file_path);
Do not forget to create complete path of your file if it is not stored in the DB. e.g
$file_path = app_path().'/images/news/'.$news->photo;
this method worked for me
First, put the line below at the beginning of your controller:
use File;
below namespace in your php file
Second:
$destinationPath = 'your_path';
File::delete($destinationPath.'/your_file');
$destinationPath --> the folder inside folder public.
This worked at laravel 8
use File;
if (File::exists(public_path('uploads/csv/img.png'))) {
File::delete(public_path('uploads/csv/img.png'));
}
First, you should go to config/filesystems.php and set 'root' => public_path() like so:
'disks' => [
'local' => [
'driver' => 'local',
'root' => public_path(),
],
Then, you can use Storage::delete($filename);
Update working for Laravel 8.x:
Deleting an image for example ->
First of all add the File Facade at the top of the controller:
use Illuminate\Support\Facades\File;
Then use delete function. If the file is in 'public/' you have to specify the path using public_path() function:
File::delete(public_path("images/filename.png"));
Using PHP unlink() function, will have the file deleted
$path = public_path()."/uploads/".$from_db->image_name;
unlink($path);
The above will delete an image returned by $from_db->image_name located at public/uploads folder
Try to use:
unlink('.'.Storage::url($news->photo));
Look the dot and concatenation before the call of facade Storage.
public function destroy($id) {
$news = News::findOrFail($id);
$image_path = app_path("images/news/".$news->photo);
if(file_exists($image_path)){
//File::delete($image_path);
File::delete( $image_path);
}
$news->delete();
return redirect('admin/dashboard')->with('message','خبر موفقانه حذف شد');
}
First make sure the file exist by building the path
if($request->hasFile('image')){
$path = storage_path().'/app/public/YOUR_FOLDER/'.$db->image;
if(File::exists($path)){
unlink($path);
}
Try it :Laravel 5.5
public function destroy($id){
$data = User::FindOrFail($id);
if(file_exists('backend_assets/uploads/userPhoto/'.$data->photo) AND !empty($data->photo)){
unlink('backend_assets/uploads/userPhoto/'.$data->photo);
}
try{
$data->delete();
$bug = 0;
}
catch(\Exception $e){
$bug = $e->errorInfo[1];
}
if($bug==0){
echo "success";
}else{
echo 'error';
}
}
the easiest way for you to delete the image of the news is using the model event like below
and the model delete the image if the news deleted
at first you should import this in top of the model class use Illuminate\Support\Facades\Storage
after that in the model class News you should do this
public static function boot(){
parent::boot();
static::deleting(function ($news) {
Storage::disk('public')->delete("{$news->image}");
})
}
or you can delete the image in your controller with
this command
Storage::disk('public')->delete("images/news/{$news->file_name}");
but you should know that the default disk is public but if you create folder in the public folder and put the image on that you should set the folder name before $news->file_name
This is the way I upload the file and save it into database and public folder and also the method I delete file from database and public folder.
this may help you and student to get complete source code to get the task done.
uploading file
at the first if you save file into database by giving path public_path() once it not need to used in delete method again
public function store_file(Request $request)
{
if($request->hasFile('file'))
{
$fileExtention = $request->file('file')->getClientOriginalExtension();
$name = time().rand(999,9999).$request->filename.'.'.$fileExtention;
$filePath = $request->file('file')->move(public_path().'/videos',$name);
$video = new Video_Model;
$video->file_path = $filePath;
$video->filename = $request->filename;
$video->save();
}
return redirect()->back();
}
deleting file
from database and public folder as you saved
public function delete_file(Request $request)
{
$file = Video_Model::find($request->id);
$file_path = $file->file_path;
if(file_exists($file_path))
{
unlink($file_path);
Video_Model::destroy($request->id);
}
return redirect()->back();
}
Its a very old thread, but I don't see that the solution is here or the this thread is marked as solved. I have also stuck into the same problem I solved it like this
$path = public_path('../storage/YOUR_FOLDER_NAME/YOUR_FILE_NAME');
if (!File::exists($path))
{
File::delete(public_path('storage/YOUR_FOLDER_NAME/YOUR_FILE_NAME'));
}
The key is that you need to remove '..' from the delete method. Keep in mind that this goes true if you are using Storage as well, whether you are using Storage of File don't for get to use them like
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use File; // For File
use Storage; // For Storage
Hope that it will help someone.
For Delete files from the public folders, we can use the File::delete function into the Laravel. For use File need to use File into the controller OR We can use \File. This consider the root of the file.
// Delete a single file
File::delete($filename);
For delete Multiple files
// Delete multiple files
File::delete($file1, $file2, $file3);
Delete an array of Files
// Delete an array of files
$files = array($file1, $file2);
File::delete($files);
Two ways to delete the image from public folder without changing laravel filesystems config file or messing with pure php unlink function:
Using the default local storage you need to specify public subfolder:
Storage::delete('public/'.$image_path);
Use public storage directly:
Storage::disk('public')->delete($image_path);
I would suggest second way as the best one.
Hope this help other people.
If you store your image in folder public, try this steps:
For example your image is sample.jpg and your path is public/img/sample.jpg
so this codes will delete your image
use Illuminate\Support\Facades\File;
.
.
.
public function deleteImage(){
$imgWillDelete = public_path() . '/img/sample.jpg';
File::delete($imgWillDelete);
}
Follow the steps carefully to get the image first=>
$img = DB::table('students')->where('id',$id)->first();
$image_path = $img->photo;
unlink($image_path);
DB::table('students')->where('id',$id)->delete();
For delete file from folder you can use unlink and if you want to delete data from database you can use delete() in laravel
Delete file from folder
unlink($image_path);
For delete record from database
$flight = Flight::find(1);
$flight->delete();
public function update(Request $request, $id)
{
$article = Article::find($id);
if($request->hasFile('image')) {
$oldImage = public_path($article->image);
File::delete($oldImage);
$fileName = time().'.'.$request->image->extension();
$request->image->move(public_path('uploads/'), $fileName);
$image ='uploads/'.$fileName;
$article->update([
'image' => $image,
]);
}
$article->update([
'title' => $request->title,
'description' => $request->description,
]);
return redirect()->route('admin.article.index');
}
you can delete file and its record like wise:
public function destroy($id)
{
$items = Reports::find($id); //Reports is my model
$file_path = public_path('pdf_uploads').'/'.$items->file; // if your file is in some folder in public directory.
// $file_path = public_path().'/'.$items->file; use incase you didn't store your files in any folder inside public folder.
if(File::exists($file_path)){
File::delete($file_path); //for deleting only file try this
$items->delete(); //for deleting record and file try both
}
return redirect()->back()->with('message','client code: '.$items->receipt_no.' report details has been successfully deleted along with files');
}
note: items->file is my attribute in database where I have stored the name of the file like so,
I have stored the file in the directory "public/pdf_uploads/filename"
Don't forget to add this in your header
use Illuminate\Support\Facades\File;
For File Syntax:
if(File::exists(public_path('upload/test.png'))){
File::delete(public_path('upload/test.png'));
}else{
dd('File does not exists.');
}
For Storage Syntax:
if(Storage::exists('upload/test.png')){
Storage::delete('upload/test.png');
/*
Delete Multiple File like this way
Storage::delete(['upload/test.png', 'upload/test2.png']);
*/
}else{
dd('File does not exists.');
}
Common Method is :
#unlink('/public/admin/pro-services/'.$task->pro_service_image);

Resources