Get image from resources folder - Laravel - laravel

Can I get and display an image in view from a resources folder instead of public folder? If yes, how can I do that?

resources folder should not be used to store images
That's not where public, static assets (like images, js, css etc) should be.
Put them inside public/ folder
The resources/assets/ directory is for storing pre-processed assets, so to speak.
For example, if you have 3 different CSS files but want to merge them
into one and render that new single file in the browser (to increase
page load speed). In this scenario, the 3 CSS files will be put
somewhere inside resources/assets/.
These files can then be processed, and the new merged file will go inside public.
Reference:
https://laracasts.com/discuss/channels/laravel/image-assets?page=1

You can make a route specifically for displaying images.
Route::get('/resources/app/uploads/{filename}', function($filename){
$path = resource_path() . '/app/uploads/' . $filename;
if(!File::exists($path)) {
return response()->json(['message' => 'Image not found.'], 404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
now you can go to localhost/resources/app/uploads/filename.png and it should display the image.reference How to get image from resources in Laravel?
But again say that resources folder should not be used to store images That's not where public, static assets (like images, js, css etc) should be. as #sehdev says his answer..

Anwsear to your question is in Laravel's doc: https://laravel.com/docs/5.7/helpers#method-app-path
$path = base_path('resources/path/to/img_dir');

You can create an symlink:
ln -s /path/to/laravel/resources/images /path/to/laravel/public/images
Although as other users have already pointed out, the resource directory is not intended to be used publicly.

I agree with #sehdev.
However, if you still want to serve your image from resources directory, here is a solution that gets the job done.
In your view:
<img src="/your-image" />
In Route:
Route::get('/your-image', function ()
{
$filepath = '/path/to/your/file';
$file = File::get($filepath);
$type = File::mimeType($filepath);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
$response->header("Content-Length", File::size($filepath));
return $response;
})
this is not the best solution. I suggest you to move your assets to public directory.
Edit: Use laravel functions. I suggest not to take file path from url because it may subject to Directory Traversal.

Related

user uploaded images should be stored in the project like public/userprofileimage.jpg or it will be affected by version control

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.

How to display PDF Documents on the browser using a View in Laravel 5.8

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" >

laravel blade include files with relative path

In laravel blade system when we want to include a partial blade file we have to write the full path every time for each file. and when we rename a folder then we will have to check every #include of files inside it. sometimes it would be really easy to include with relative paths. is there any way to do that?
for example we have a blade file in this path :
resources/views/desktop/modules/home/home.blade.php
and I need to include a blade file that is near that file :
#include('desktop.modules.home.slide')
with relative path it would be something like this :
#include('.slide')
is there any way to do this?
if someone still interest with relative path to current view file, put this code in the boot method of AppServiceProvider.php or any provider you wish
Blade::directive('relativeInclude', function ($args) {
$args = Blade::stripParentheses($args);
$viewBasePath = Blade::getPath();
foreach ($this->app['config']['view.paths'] as $path) {
if (substr($viewBasePath,0,strlen($path)) === $path) {
$viewBasePath = substr($viewBasePath,strlen($path));
break;
}
}
$viewBasePath = dirname(trim($viewBasePath,'\/'));
$args = substr_replace($args, $viewBasePath.'.', 1, 0);
return "<?php echo \$__env->make({$args}, \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
});
and then use
#relativeInclude('partials.content', $data)
to include the content.blade.php from the sibling directory called partials
good luck for everyone
you need to create custom blade directive for that, the native include directive doesn't work like that.
read this page to learn how to create custom blade directive :
https://scotch.io/tutorials/all-about-writing-custom-blade-directives
\Blade::directive('include2', function ($path_relative) {
$view_file_root = ''; // you need to find this path with help of php functions, try some of them.
$full_path = $view_file_root . path_relative;
return view::make($full_path)->render();
});
then in blade file you can use relative path to include view files :
#include2('.slide')
I tried to tell you the idea. try and test yourself.
There’s now a package doing both relative and absolute includes (lfukumori/laravel-blade-include-relative) working with #include, #includeIf, #includeWhen, #each and #includeFirst directives. I just pulled it in a project, it works well.
A sleek option, in case you want to organise view files in sub-folders:
public function ...(Request $request) {
$blade_path = "folder.subfolder.subsubfolder.";
$data = (object)array(
".." => "..",
".." => $..,
"blade_path" => $blade_path,
);
return view($data->blade_path . 'view_file_name', compact('data'));
}
Then in the view blade (or wherever else you want to include):
#include($blade_path . 'another_view_file_name')

Remove unused Images/files from upload folder laravel

I have laravel5.4 application.I want to remove unused images/files from my upload folder which is not available in my database.
For example :
I have 50 images in my upload folder for user profile but some of the image not use for any user.i think he removed or update his image from frontend.
Yes i know we need to code to remove file when user update or remove profile picture at a time also delete from upload folder.but my app run from many time and i want to remove unused file using script not manually beacause i have lot's of files so it's hard to check and remove file manually.anyone can you please help me for create any function for remove file from folder.
Sorry for my bad English.
I use something like this in my AdminController to remove images by clicking on a button.
Maybe you need to change the path or extensions
public function deleteUnusedImages()
{
$file_types = [
'gif',
'jpg',
'jpeg',
'png'
];
$directory = public_path();
$files = File::allFiles($directory);
foreach ($files as $file)
{
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (in_array($ext, $file_types)) {
if(DB::table('users')->where('votes', '=', $file)->count())
continue; // continue if the picture is in use
echo 'removed' . basename($file)."<br />";
unlink($file); // delete if picture isn't in use
}
}
}

Laravel display image from path which is in database

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.

Resources