How to manipulate & resize images in laravel 5.5 - php

I'm using The Public Disk which is local driver. I create a symbolic link from public/storage to storage/app/public using this given command php artisan storage:link. I didn't change anything as mentioned in laravel filesystem documentation. But i'm not able to view the image with asset helper. File_path is storing in database but still images are broken.
Controller:
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
$slide = new Slider();
$slide->title = $request->title;
$slide->description = $request->description;
//uploading image
if ($request->hasFile('file')) {
$file = $request->file('file');
$slide->file_name = str_random(40) . $file->getClientOriginalName();
$slide->file_size = $file->getClientSize();
$slide->file_mime = $file->getClientMimeType();
$slide->file_path = $file->storeAs('public', $slide->file_name);
}
$slide->status = $request->status;
$slide->save();
return redirect()->route('slider.index')->with('success', 'Done');
}
I'm using storeAs method, which receives the path, the file name.
Database:
View:
<td><img src="{{ asset($slide->file_path) }}" class="content" width="25"></td>
StoreAs method returns the path which is public/filename.jpg and images store into public/storage folder. How do i view the images?

The public and S3 storages support the url method that you can use to get the correct URL for the image
<td><img src="{{ Storage::url($slide->file_path) }}" class="content" width="25"></td>

You should add storage prefix to your asset:
<td><img src="{{ asset('storage/' . $slide->file_path) }}" class="content" width="25"></td>

Related

Laravel not showing images form storage on shared server

My images are not showing up on site. I get 404
Symlink function is disabled but I used this instead:
ln -s /home/USERNAME/my_app/storage/app/public /home/USERNAME/public_html/storage
to create it.
Url on site looks good https://my_app.com/storage/logo.png
Binded public path to public_html
$this->app->bind('path.public', function() {
return '/home/my_app/public_html';
});
I tried to get images in these two ways:
<img class="card-img-top" src="{{$post->getFirstMedia()->getUrl() }}" alt="Card image cap">
And tired with asset()
<img class="card-img-top" src="{{asset($post->getFirstMedia()->getUrl()) }}" alt="Card image cap">
But still nothing.
The src link looks good https://my_app.com/storage/logo.png but no image, just 404.
SOLUTION:
/home/USERNAME/my_app/ folder permissions were 700, changed to 755 and it works now!
If your public directory name is public_html in laravel project's root then you must have to change the links key value to in config/filesystems.php
'links' => [
base_path('public_html/storage') => storage_path('app/public'),
],
You can create code in route file to run laravel command in your cpanel.
Route::get('/foo', function () {
Artisan::call('storage:link');
});
If you still can't create symlink then here is the protected way to get your files from the storage folder
You can Get route to get files from storage directly.
Route::get('storage/{filename}', function ($filename) {
$path = storage_path('public/' . $filename);
if (!File::exists($path)) {
abort(404); // return 404 page
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});

Retrieving multiple files and display in Vue component

I am processing files by extension and storing images, files, and pdf's inside of respective folders located in the public storage.
Php artisan link:storage has already been run. Files are being properly sorted and stored in the correct locations.
The portion of documentation that says to create the URL link using "echo asset()" is a bit unclear to me and I believe that's where the issue lies. Where am I supposed to echo the asset? I was unable to do so in the vue component.
However, on the front end (Vue Component using Axios to pass data) it seems that the :src is only getting the file path stored in the Database and not grabbing the actual file from the storage location.
Here is the portion of the component where the image should display:
<div v-for="image in post.images" :key="image.id">
<img width="220" height="250" :src=" './storage' + image.post_image_path " />
</div>
Here is my Controller function that stores the images:
public function store(Request $request)
{
// get the data from vue component
$title = $request->title;
$description = $request->description;
$author_id = Auth::user()->id;
$images = $request->images;
// creating the new post with the data above
$post = Post::create( [
'title' => $title,
'description' => $description,
'author_id' => $author_id
]);
// we are receiving an array in the image, we need to do a foreach to grab the files that the image has
foreach($images as $image) {
$name = $image->getClientOriginalName();
$ext = $image->getclientoriginalextension();
// creating the extension so we can filter the query above
$ext_images = array('jpg', 'png');
$ext_files = array('pdf', 'doc', 'docx','txt');
$ext_videos = array('mp4', 'mov', 'avi');
// we are proccesing the images files
if (in_array($ext, $ext_images)) {
$imagePath = Storage::disk('local')->put('/post_images' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
}
// we are proccessing standard files and saving if
elseif (in_array($ext, $ext_files)) {
$imagePath = Storage::disk('local')->put( '/post_files' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
}
// we are processing the media files (video) and saving if
elseif (in_array($ext, $ext_videos)) {
$imagePath = Storage::disk('local')->put('/post_videos' , $image);
Image::create( [
'post_id' => $post->id,
'post_image_path' => '/local/' . $imagePath,
]);
};
}
return $post;
With the current controller set up files are organized into their respective folders and storing in the "storage/app/specified folder name". This is working correctly, the only issue retrieving the records after they have been created.
PARTIALLY RESOLVED:
By changing the storage location to:
$image->move(public_path('post_images'), $name);
instead of
$imagePath = Storage::disk('local')->put('/post_images' , $image);
While I have a viable work around, understanding why the storage wasn't working would be greatly appreciated.
The asset helper method is going to return to full proper path of the image folder.
Since you are not calling the method (Or you can't since you are working in a vue component), you have to set the base of your path yourself and concat the image name.
By default Laravel's public directory is the entry point, so this should work, if the image is placed properly:
<img width="220" height="250" :src=" '/storage' + image.post_image_path" />
Saving the image like:
$image->move(public_path('post_images'), $name);
resolved the issue.

How to display an storage image Laravel 5.2

I want tho disply an image on my view, but i receive: File not found.
The two errors:
FileNotFoundException in FilesystemAdapter.php line 61:
storage/app/public/covers/teste-bravo_cover.jpg
FileNotFoundException in Filesystem.php line 386: File not found at
path: storage/app/public/covers/teste-bravo_cover.jpg
But the image is in the correct folder:
Well, in Laravel 5.2 storage:link won't work.
Image store on disk -works fine to store the image
if($cover){
dump("ok1");
Storage::disk('public_covers')->put($covername, File::get($cover));
$coverObject = New Cover();
//path com o nome do arquivo
$coverObject->imagePath = 'storage/app/public/covers/'.$covername;
dump($coverObject->imagePath);
}
//Salva a capa com o path para o arquivo
$coverObject->save();
My filesystems (with the "public_covers" disk) -works fine to store the image
'public_covers' => [
'driver' => 'local',
'root' => storage_path('app/public/covers'),
'visibility' => 'public',
],
View code: (if movie have cover, show them)
#if($movie->cover)
<img src="{{route('cover.image', [$movie->cover])}}" />
#endif
Route code, directing to controller method
Route::get('/movieimage/{coverId}',
[
'as' => 'cover.image',
'uses' => 'MovieController#getimage'
]
);
Controller Method to take the image
public function getimage($coverId){
$movie = Cover::find($coverId);
//dump($movie);
$imagePath = $movie['imagePath'];
dump($imagePath);
$file = Storage::disk('public_covers')->get($imagePath);
$response = Response::make($file, 200);
return $response;
}
you can try
Need to include this
use Illuminate\Support\Facades\Storage;
And set in controller or route
Route::get('storage/{filename}', function ($filename)
{
$files = Storage::files('logs'); // set repo name of storage folder
$path = storage_path('public/' . $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;
});
I am new to laravel. I had the same problem though am on laravel 5.8. I had created the symlink to display a pdf as a view but the FileNotFoundException persisted.
I ended up accessing the pdf using this url localhost:8000/storage/filename.ext.
After running ln -s /path/to/laravel/storage/public /path/to/laravel/public/storage or php artisan storage:link a storage folder is added to your appname/public directory. I think that once the link is created we access the images in the storage through the public link created. Try accessing the images via the new /appname/public/storage/app/pathtoimage folder created in the public directory and not pointing directly to the /appname/storage folder
<img src={{asset('/storage/pathtoimg')}} /> # using storage folder in public
Check this solution will work for you
How I solved my problem:
First of all, save the files on "public" folder.
On my filesystems.php i change my disk. Now my root are "public_path" and not "storage_path"
'public_covers' => [
'driver' => 'local',
'root' => public_path('images/covers'),
'visibility' => 'public',
],
My controller method
public function store(Request $request){
$cover = $request->file('cover');
$inputs = $this->request->all();
$this->validate($this->request, [
'title' => 'required|max:255',
'description' => 'required',
'gender' => 'required',
'secondGender' => 'required',
'year' => 'numeric|min:1900|max:2100',
'lenght' => 'numeric|min:10'
]);
//build movie model object
$movie = New Movie();
$movie->user_id = \Auth::user()->id;
$movie->gender_id = $inputs['gender'];
$movie->secondgender_id = $inputs['secondGender'];
$movie->title = $inputs['title'];
$movie->slug = str_slug($inputs['title']);
$movie->description = $inputs['description'];
$movie->lenght = $inputs['lenght'];
$movie->year = $inputs['year'];
//TODO Mudar a composição do nome da foto para impedir que no futuro se sobreponha uma capa com outro filme que venha a ter o mesmo nome
//TODO: Change the name createan to avoid overwrite the cover with an movie with the same name
$covername = str_slug($inputs['title']).'_cover' .'.jpg';
//if have an cover file
if($cover){
//storage the file on my public_covers (look my filesystems.php)
Storage::disk('public_covers')->put($covername, File::get($cover));
$coverObject = New Cover();
//path com o nome do arquivo
//path with the file name
$coverObject->imagePath = 'images/covers/'.$covername;
$coverObject->save();
$movie->cover_id = $coverObject->id;
}
$movie->save();
return redirect()
->route('user.dashboard')
->with([
'success' => 'Filme adicionado com sucesso!',
]);
}
My view image code
#if($movie->cover)
<img class="cover" src="{{ asset($movie->cover->imagePath) }}" alt="{{ $movie->title }}"">
#else
<img class="cover" src="{{ asset('images/noimage.jpg') }}" alt="{{ $movie->title }}">
#endif

Laravel upload images to database

I'm trying upload image:
View (part):
<input type="file" name="image" />
Countoller:
public function store(Request $request){
dump($request->all());
$this->validate($request,[
'title'=>'required|max:255',
// 'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'text'=>'required',
]);
$imageName = time().'.'.$request->image->getClientOriginalExtension();
$request->image->move(public_path('images'), $imageName);
dump($request);
$data=$request->all();
dump($data);
$aticle=new Article;
$aticle->fill($data);
}
Dump request:
"title" => "fgdfd"
"alias" => "dg"
"desc" => "fdgfgd"
"text" => "gd"
"image" => "IMG_0002.JPG"
"tag" => "hg"
How do I put an image in MySql database?
As the docs describe, you should be using the file() method on the $request to access the uploaded file, not the name of your file field.
In your case, that means:
// Use the file() method to access the uploaded file
$imageName = time() . '.' . $request->file('image')->getClientOriginalExtension();
// storeAs() allows you to move a file while specifying a new filename.
// $path will be the fully qualified path to the file, including filename.
$path = $request->file('image')->storeAs(public_path('images'), $imageName);
It isn't clear from your question whether you want to save the file path in the database, or the actual binary file contents, as a BLOB. Here's how to do both:
// Create new article
$aticle=new Article;
$aticle->fill($data);
// Either save the path to the uploaded image in the DB
$aticle->featured_image = $path;
$aticle->save();
// OR
// Save the file binary contents in the DB
$aticle->featured_image = file_get_contents($path);
$aticle->save();
Ideally, you'll save the file to a location and then store the path to that file in the database.
What version of Laravel are you on ? If you're on 5.3 or higher you can:
$path = $request->image->store('path/to/save/the/file');
this will save the file with a random name, then just store that path to the database.
or you can:
$path = $request->image->storeAs('path/to/save/the/file', 'filename.jpg');
if you want to specify the saved file name.
This work's for me:
Step 1
Use Intervention Image package for manipulating images. You'll install it via composer. Run the command:
composer require intervention/image
Step 2
After installing Intervention Image, you need to add service providers and facade. Open our config/app.php file and add following lines. In the $providers array add the service providers for this package.
Intervention\Image\ImageServiceProvider::class
Step 3
Add the facade of this package to the $aliases array.
'Image' => Intervention\Image\Facades\Image::class
Step 4
And finally publish the configuration using following command:
$ php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravel5"
Step 5 Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\yourmodel;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Input;
use Response;
use Image;
class YourController extends Controller
{
public function create()
{
return view('yourview.create');
}
public function store(Request $request)
{
$file = Input::file('pic');
$img = Image::make($file);
Response::make($img->encode('jpeg'));
$var = new YourModel;
$var->pic = $img;
$var->save();
return redirect()->route('yourview.index')
->with('success','Success.');
}
Step 6 View
<form action="{{ route('yourview.store') }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="row">
<div class="col-xs-4 col-sm-4 col-md-4">
<div class="form-group">
<strong>Image:</strong>
<input type="file" id="pic" name="pic" class="form-control"></input>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<button type="submit" class="btn btn-primary">Send</button>
</div>
</div>
</form>

Display pdf file from local disk in Laravel 5?

I have a Laravel 5.5 app where users with administrator privileges can upload files. After they upload the files I'd like them to be able to view the file in the administrator dashboard.
I have a DocumentController.php that handles the file upload to the local disk:
public function store(Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
// validate that the document is a pdf and
// that required fields are filled out
$this->validate($request, [
'title' => 'required',
'description' => 'required',
'user_id' => 'required|exists:users,id',
'document_path' => 'required|mimes:pdf'
]);
$file = $request->file('document_path');
$path = $file->store('documents/' . $request->user_id);
$document = Document::create([
'user_id' => $request->user_id,
'title' => $request->title,
'description' => $request->description,
'file_path' => $path
]);
return redirect($document->path());
}
This method takes the file from the form, makes sure it is a pdf and then saves the file to storage/app/documents/{user_id}. It then creates a Document record in the database and forwards to the URL based on the document id: /admin/document/{ $document->id }
That route is defined as Route::get('/admin/document/{document}', 'DocumentController#show');
Where in the controller I pass the document to the view:
public function show(Document $document, Request $request)
{
// check to make sure user is an admin
$request->user()->authorizeRoles('admin');
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
return view('admin.document', compact('document', 'storagePath'));
}
On that page I would like to display the pdf document.
resources/views/admin/document.blade.php
#extends('layouts.app')
#section('content')
<div class='container'>
<div class='row'>
<div class='col-sm-2'>
<a href='/admin'>< Back to admin</a>
</div>
<div class='col-sm-8'>
{{ $document }}
<embed src="{{ Storage::url($document->file_path) }}" style="width:600px; height:800px;" frameborder="0">
</div>
</div>
</div>
#endsection
I have tried using the $storagePath variable and Storage methods but cannot get the pdf file to display within the iframe.
Using local file storage how would I display the file in the browser? Also, I've protected the route so that only admins can view the document's page but what is the best way to secure the path to the document itself?
If you want your files to be protected (only admin can access them), then you need to create a new route and new DocumentController method getDocument
Add new route
Route::get('documents/pdf-document/{id}', 'DocumentController#getDocument');
In DocumentController, add
use Storage;
use Response;
Add new method that will read your pdf file from the storage and return it back
public function getDocument($id)
{
$document = Document::findOrFail($id);
$filePath = $document->file_path;
// file not found
if( ! Storage::exists($filePath) ) {
abort(404);
}
$pdfContent = Storage::get($filePath);
// for pdf, it will be 'application/pdf'
$type = Storage::mimeType($filePath);
$fileName = Storage::name($filePath);
return Response::make($pdfContent, 200, [
'Content-Type' => $type,
'Content-Disposition' => 'inline; filename="'.$fileName.'"'
]);
}
In your view you can show the document like this
<embed
src="{{ action('DocumentController#getDocument', ['id'=> $document->id]) }}"
style="width:600px; height:800px;"
frameborder="0"
>
Shorter version of that Response::make() from #ljubadr answer:
return Storage::response($document->file_path)
<embed
src="{{ url('/filepath') }}"
style="width:600px; height:800px;"
frameborder="0">

Categories