Laravel 7.28 "the file does not exist error - php

i'm building a project with laravel 7.28. i list all of documents with foreach without a problem. then i listed and linked all of the documents like this
#foreach($customer->documents as $document)
<div class="col-md-2">
#if($document->extension == 'pdf')
<a href="{{ route('downloadDocument', $document->id) }}">
<img src="/assets/images/pdf_icon.png" alt="">
</a>
#endif
#if($document->extension == 'doc' || $document->extension == 'docx')
<a href="{{ route('downloadDocument', $document->id) }}">
<img src="/assets/images/docx_icon.png" alt="">
</a>
#endif
#if($document->extension == 'xlsx')
<a href="{{ route('downloadDocument', $document->id) }}">
<img src="/assets/images/xlsx_icon.png" alt="">
</a>
#endif
#if($document->extension == 'jpg' || $document->extension == 'jpeg'|| $document->extension == 'png'|| $document->extension == 'svg')
<a href="{{ route('downloadDocument', $document->id) }}">
<img src="/assets/images/photo1.png" alt="">
</a>
#endif
</div>
#endforeach
then i wrote route like this;
Route::get('downloadDocument/{id}', 'CustomerController#downloadDocument')->name('downloadDocument');
downloadDocument function is;
public function downloadDocument($id)
{
$path = '/assets/uploads/customers/';
$file = Upload::findOrFail($id);
$pathToFile = $path . $file->media;
return response()->download($pathToFile);
}
i'm sure that i have that file on database and on server or local. although i get error;
is there anyone to help me?

URL Path vs System Path
I believe you're confusing URL path from system path.
Browser see files with URL paths like this (http://foobar.com/assets/uploads/customers/xxx.png). When you print things to the template, the files are referenced in HTML as URL path. A path like /assets/uploads/customers/xxx.png is simply
URL with implicit domain.
From the server program perspective, the file is stored in your harddisk with system paths like:
C:\My Websites\foobar\public\assets\uploads\customers\xxx.png (Windows); or
/home/foobar/web/public/assets/uploads/customers/xxx.png (Linux or Macos).
So, although these paths look different, they might be referencing the same file. Just from different perspective.
How to correctly build $pathToFile?
The $pathToFile parameter of download needs to be the system path to the file. I don't believe the png file is at /assets/uploads/customers/xxx.png in your system (Putting an assets folder in system root / or C:\ is quite unusual).
If the assets/ folder is in your Laravel's public/ folder, you can rewrite your method with public_path() like this:
public function downloadDocument($id)
{
// Note: remove leading slash
$path = 'assets/uploads/customers/';
$file = Upload::findOrFail($id);
// Note: apply public_path() helper function
$pathToFile = public_path($path . $file->media);
return response()->download($pathToFile);
}
Documentation about public_path() in Laravel 7.x:
public_path()
The public_path function returns the fully qualified path to the public directory. You may also use the public_path function to generate a fully qualified path to a given file within the public directory:
$path = public_path();
$path = public_path('css/app.css');

Related

Image is being stored correctly but can't display on Laravel Blade

The image is being correctly stored in the storage/app/public/images folder however when I try to display the image with the code below , it returns nothing. I will also attach my image Controller function
I have tried the following
<img src = "{{ asset('storage/app/public/images/artist.jpg') }}" />
<img class="rounded-circle" src="/storage/images/{{ $user->image }}" />
Controller function
public function update_image(Request $request){
$request->validate([
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$user = Auth::user();
$imageName = $user->id.'_image'.time().'.'.request()->image->getClientOriginalExtension();
$request->image->storeAs('images',$imageName);
$user->image = $imageName;
$user->save();
return back()
->with('success','You have updated image.');
}
That's cause you are storing the images in the storage folder and not in the public folder.
Run php artisan storage:link
and write in your code <img src = "{{ asset($user->image) }}" />
https://laravel.com/docs/5.5/filesystem#the-public-disk
Your asset() helper should be point to the following:
asset('storage/images/artist.jpg');
This is because the new symlinked folder can be found at public/storage and the asset() helper creates links to the public folder. Removing app/public from the string should solve the problem.

Symfony 4 file controller helper how to convert binary file to HTML compatible?

Trying to retrieve an image from outside public. I have been using file controller helper but still can't get it to work:
here is my code that is returned as AJAX to update the IMG SRC path
$imgPATH = $this->getParameter('kernel.project_dir').'/uploads/user_profile_pictures/';
$ext = [".png", ".jpg", ".jpeg", ".gif"];
foreach ($ext as $x) {
$imgPath = $this->getParameter('kernel.project_dir').'/uploads/user_profile_pictures/'.$usertoPic.$x;
if (file_exists($imgPath)) {
return $this->file($imgPath , 'userProfilePicture.png' , ResponseHeaderBag::DISPOSITION_INLINE);
}
}
The image is found by PHP but I get the following broken HTML in the browser; I think this is because it is binary ? how can I convert it to HTML compliant ?
<img id="userIMG" src="�PNG��IHDR���S���S���lЬW���pHYs��.#��.#x�v��OiCCPPhotoshop ICC profile��xڝSgTS�=���BK���KoR RB���&*!J�!��Q�EEȠ�����Q,������������{�kּ������>�����H3Q5��B�������.#�$p��d!s�#��~<<+"���x���M��0���B�\���t�8K��#z�B��#F���&S���`�cb��P-�`" �������{�[�!���="" e�d�h;���v�e�x0�fk�9��-�0iwfh��������="" �0q��)�{�`�##x����f�w<�+��*��x��<�$9e�[-qww.(�i+6aa�#.�y�2�4�����������x����6��_-��"bb���ϫp#���t~��,="" ��;�m��%�h^�u��f�#�����w�p�~<<e���������j�b[a�w}�g�_�w�l�~<�����$�2]�g�����l�ϒ="" �b��g�����"�ib�x*�qq�d���2�"�b�)�%��d��,�="">
Your browser cannot have access to a file that is not in the public (for Symfony 4) folder. That is pretty much the whole point of having a "public" directory.
What you can do is serving the file directly as a binary response given a certain link in your app, like documented here:
https://symfony.com/blog/new-in-symfony-3-2-file-controller-helper
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ImgController extends Controller
{
/**
* #Route("/get-my-img")
*/
public function getImg()
{
$basePath = $this->getParameter('kernel.root_dir').'/uploads/user_profile_pictures/';
return $this->file($basePath . "img.png");
}
}
// this should work quite simple:
// site/public/css/style.css
<link href="{{ asset('css/style.css') }}" rel="stylesheet" />
// site/upload/favicon.ico
<img src="{{ asset('../upload/favicon.ico') }}" />
$target_dir = '/upload/favicon.ico'; // param in config
$file = $this->getParameter('kernel.project_dir') . $target_dir;
if(is_file($file)) dump('found: ' . $file);

File download not working in Laravel 5?

I have stored a file in /public/storage/attachment and the file has a hashname which is stored in my database as well in the attachments table filehashname column
public/attachment/N52lbwmzubAcgUfHYhCC4A6NFBniIVmK.pdf
In the view I'm displaying the file as a link so that when the user clicks the link the file gets downloaded.
<a href="{{ URL::to( '/download/'.$post->attachments[0]->filehashname) }}">
{{ $post->attachments[0]->filename }}
</a>
web.php
Route::get('/download/{filehashname}', 'PostController#downloadAttachment');
PostController
public function downloadAttachment($filehashname)
{
$file= public_path('/storage/attachment/'.$filehashname);
return response()->download($file, 'demo.pdf');
}
But this does not download the file it opens the URL http://localhost:8000/download/public/attachment/N52lbwmzubAcgUfHYhCC4A6NFBniIVmKfctqMNOq.pdf with Page Not Found
If I hardcode the filename and click the link then it downloads but dynamically passing the name of the file in url gives Page Not Found error.
How to solve this?
If your file is stored in public directory then try public_path() and if your file is saved in storage directory then try storage_path()
$destination = storage_path('storage/attachment/'); // if your storage folder contains only attachement folder then like this :- storage_path('attachment/');
or
$destination = public_path('storage/attachment/');
$pathToFile = $destination.$filehashname;
return response()->download($pathToFile,'demo.pdf');
Hope it helps :)
You just need to add downlaod option in anchor tag
<a href="{{ URL::to( '/download/'.$post->attachments[0]->filehashname) }}" download >
{{ $post->attachments[0]->filename }}
</a>
This is being answered here
Try this
$myFile = public_path($filehashname); # place file in public/ and check this;
# If works add this public_path("storage/attachment/".$filehashname);
$headers = ['Content-Type: application/pdf'];
$newName = "demo.pdf";
return response()->download($myFile, $newName, $headers);
public_path()

Laravel 5.3 storage cant find uploaded file

I am using laravel Filesystem to store images, the image will be uploaded inside the default storage, example:
/home/user/Projects/mywebapp/storage/app/images/posts/1/e392e17926559e7cc4e7934f.png
I didnt change the config/filesystem.php and here is my controller method to upload an image,
public function storeImage( Request $request ) {
$image = $request->file( 'image' )->store( 'images/posts/'.Auth::user()->id );
echo Storage::url( $image ); // <- print the url of the uploaded image
}
This would print the image url like this,
http://localhost:8000/storage/images/posts/1/e392e17c6a8d7926559e8e7cc4e7934f.png
But the image file is not accessable from the browser!
I dont want to use php to dynamically fetch the images, i just wanted to make them publicly accessable over http. How to display the image?
you just have to make a change in config\filesystems.php form
'default' => local,
to 'default' => public,
then in console run php artisan storage:link
then try the above code and it will work
For me it worked when I added "../" to the url of the file:
#foreach($arquivos as $i)
<li class="list-group-item"> <img src="{{ asset('img/pdf.png') }}" /> {{ $i -> nome }} </li>
#endforeach
And I am saving the file like this:
$ext = $request->arquivo->extension();
$path = $request->arquivo->storeAs('/relatorios', $nameoffile. "." . $ext);

How to display image from aws s3 in blade laravel 5.2

I have created a method for getting the data(image file) from aws S3 like this :
public static function getImage ($imagePath)
{
if(Storage::exists($imagePath))
{
return Storage::disk('s3')->get($imagePath);
}else
{
return 'No Image';
}
}
I'm sure that those image is exist on the aws, so there is no problem with that.
And then I use above method as the src in my blade view like this :
{!!Html::image(getImage($myPath),'logo',['width'=>60,'height'=>55])!!}
$myPath here already point to the specific file on aws for example : bucket/file.jgp. But when I run my webpage, this Html::Image gives a view like this :
What's going on here ? Why Html::image can't render my image file ? :(
Works on Laravel 6.x
<img src="{{Storage::disk('s3')->url($imagePath)}}">
You can use Storage::url($imagePath). Please see Filesystem / Cloud storage on laravel docs
{!!Html::image(<Your S3 bucket URL>.$myPath),'logo',['width'=>60,'height'=>55])!!}
You can save the S3 URL in a config file and use the config value instead of writing actual value everytime.
I had the same issue. This code snippet solved it
<img src="{!! url(<path to your image>) !!}" />
First, you need to give it public promotion in the controller
$path = Storage::disk('s3')->put('profileImages/', $request->file('profile_image'), 'public');
//save image name in database
$user->profile_image = basename($path);
In blade file
<img src="{{Storage::disk('s3')->url('profileImages/' . $user->profile_image)}}" />
You can add an accessor like follow to get Image URL
It returns URL to the image and you can access it by $profile->image
public function getImageAttribute($value)
{
if ($value) {
return Storage::disk('s3')->url($value);
}
return "https://source.unsplash.com/96x96/daily";
}
I assume you save image as follow
$path = $request->file('image')->store('images', 's3');
Storage::disk('s3')->setVisibility($path, 'public');
$profile->update([
'image' => $path
]);
You can check this commit for more detail
https://github.com/itxshakil/ediary/commit/23cb4b1cb7b8a4eac68f534e8c5b6897abc6421a
I have read every solution and no one has pointed it directly. So I thought to write my answers. For this problem I just required to add this simple line and boom, it starts working. But I got access denied alert you should check that problem too.
<img class="img-responsive" src="{!! Storage::disk('s3')->url('thumbs/' . $business->image->path) !!}" alt="thumb">
This works
Storage::disk('s3')->url($imagePath)
and also from your Minio Browser.
You have to Add a policy to Read and Write
I think that private visibility of images is an important security feature.
I found a solution :-)
Method in Controller:
/**
* #param string $name : image name on bucket
* ( stored if you want into database )
*/
public function show( $name ) {
$path = config('filesystems.disks.s3.base_directory') . '/' . $name;
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = Storage::get( $path );
$base64 = 'data:image/' . $type . ';base64,' . base64_encode( $data );
return view( 'show', [ 'src' => $base64 ]);
}
The view:
...
<div class="panel panel-primary">
<div class="panel-heading"><h2>Laravel File Retrive with Amazon S3 </h2></div>
<div class="panel-body">
**<img src="{{ $src }}"/>**
</div>
</div>
...

Categories