Cannot fetch image from storage directory in laravel - laravel

The image is not shown when I display it in the index page.
My view file (index.blade.php):
<div class="row">
#if(App\News::count() > 0)
#foreach($news as $n)
<div class="col-md-8 panel border-right">
<br />
<img src="{{ asset('storage/images/news/'. $n->image) }}" width="200px" height="100px">
--$n->image returns News_1.jpg which is the image name stored in the storage directory.
<h1>First Div</h1>
</div>
#endforeach
#endif
<div class="col-md-4">
<h1>Second Div</h1>
</div>
</div>
My controller:
public function store(Request $request)
{
$this->validate($request,
[
'head' => 'required|max:191',
'title' => 'required|max:191',
'body' => 'required',
'pic' => 'required'
]);
$filename="";
$extension="";
if($request->hasFile('pic'))
{
if((News::orderBy('id', 'desc')->first()) != null)
{
$id = ((News::orderBy('id', 'desc')->first()->id)+1);
$filename = "News_" . $id;
}
else
{
$filename = "News_" . 1;
}
$extension = $request->pic->getClientOriginalExtension();
$filename = $filename . "." . $extension;
//return $request->pic->getClientOriginalName();
$request->pic->storeAs('public/images/news', $filename);
}
else
{
return redirect()->back()->withInput(Input::all())->withErrors(['message' => 'Please select a valid file.']);
}
$news = new News;
$news->head = $request->head;
$news->title = $request->title;
$news->body = $request->body;
$news->image = $filename;
$news->save();
Session::flash('success', 'The record was successfully saved.');
return redirect()->route('news.index');
}
I have already linked the storage directory with the public directory:
My directory structure:
The images are stored properly in both the Application and database but it cannot be displayed properly, when I run the app, I get the following view:
When open the image in new tab, I see the following address bar:
This is the local driver configuration:
Any help is appreciated in advance.

If your current route is /cricket and you reference an image with 'storage/images/news/news1.jpg' then the web browser is going to assume that this image is relative to the cricket resource.
Your image src needs to start with either the full URL or a / to indicate it is relative to the root folder
In this case I would hard code the URL since you have hard coded it in the asset helper anyway
<img src="/storage/images/news/{{ $n->image }}"

You can try setting your local driver to something like this:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],

Related

How can i change the image upload directory and view image url in laravel

In my script all images uploaded goes into directory "ib" but i want to change that directory to a different name eg. "imgib"
here is what i did so far. i changed the code vlues from "ib" to "imgib"
} else {
// upload path
$path = 'imgib/';
// if path not exists create it
if (!File::exists($path)) {
File::isDirectory($path) or File::makeDirectory($path, 0777, true, true);
}
// move image to path
$upload = $request->file('uploads')->move($path, $imageName);
// file name
$filename = url($path) . '/' . $imageName;
// method server host
$method = 1;
}
// if image uploded
if ($upload) {
// if user auth get user id
if (Auth::user()) {$userID = Auth::user()->id;} else { $userID = null;}
// create new image data
$data = Image::create([
'user_id' => $userID,
'image_id' => $string,
'image_path' => $filename,
'image_size' => $fileSize,
'method' => $method,
]);
// if image data created
if ($data) {
// success array
$response = array(
'type' => 'success',
'msg' => 'success',
'data' => array('id' => $string),
);
// success response
return response()->json($response);
} else {
if (file_exists('imgib/' . $filename)) {$delete = File::delete('imgib/' . $filename);}
// error response
return response()->json(array(
'type' => 'error',
'errors' => 'Opps !! Error please refresh page and try again.',
));
}
so far everything looks ok and it creates "imgib" directory automatically and all uploads go into "imgib" directory.
But the issue is, image url still uses the same old directory name.
eg. site.org/ib/78huOP09vv
How to make it get the correct url eg. site.org/imgib/78huOP09vv
Thanks for the help everyone. I managed to fix the issue by editing viewimage.blade.php
Yes of course need to clear the browser cache after editing the files.

Handling File uploads and reorder with Laravel Livewire and Filepond

I have a form in my application that allows users to create posts and while doing so upload multiple images to the post being created.
I am using Laravel Livewire and Filepond to achieve this.
The problem I am having is I need to allow the user to reorder the images (as it is a gallery and the order is important), and save the order in the database when the form in submitted.
Another issue I am running into is allowing a user to edit their post later. I need their pre-existing post images loaded in filepond, and also allow them to upload more, delete, and/or reorder.
When the user saves the post I need to be able to update my database and file system.
All info online is how to upload files, but no info on how to reorder, or pre-populate with pre-existing files.
Here is my current code for reference:
<div
x-data=""
x-init="
FilePond.setOptions({
allowMultiple: true,
allowReorder: true,
itemInsertLocation: 'after',
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
#this.upload('images', file, load, error, progress)
},
revert: (filename, load) => {
#this.removeUpload('images', filename, load)
},
load: (source, load, error, progress, abort, headers) => {
var myRequest = new Request(source);
fetch(myRequest).then(function(response) {
response.blob().then(function(myBlob) {
load(myBlob)
});
});
},
},
});
const pond = FilePond.create($refs.input, {
acceptedFileTypes: ['image/png', 'image/jpeg'],
maxFileSize: '7MB',
allowImageCrop: true,
allowReorder: true,
allowImageResize: true,
imageResizeTargetWidth: '1000px',
imageResizeTargetHeight: '1000px',
filePosterMaxHeight: '256px',
files: {{ $existingImages }} // used for when editing a post and it already has images. see php component on how I set this variable
});
"
>
<div wire:ignore wire:key="images">
<div class="form-group text-center">
<input
id="image-upload"
type="file"
x-ref="input"
multiple
data-allow-reorder="true"
data-max-file-size="3MB"
data-max-files="10"
>
</div>
</div>
</div>
My Livewire PHP component:
public $images = [];
public $existingImages;
public function mountMedia($post) {
if($post){
$this->existingImages = $post->images->map(function ($image) use ($post) {
return [
'source' => $image->id,
'options' => [
'type' => 'local',
'file' => [
'name' => $image->getUrl(),
'size' => $image->file_size,
'type' => $image->mime_type,
],
'metadata' => [
'poster' => $image->getUrl(),
'position' => $image->position
],
],
];
});
}
}
public function saveImage($file, $post, $position) {
// Create a unique random string
$randString = Str::random(3);
// Get time
$time = time();
// Set file name
$filename = $time. '-' . $randString.'-'.auth()->user()->id;
$extension = '.'.$file->getClientOriginalExtension();
// Save images for gallery
$regImage = $file->storeAs('/'. $post->id, $filename.$extension, 'post_images');
// Create a new image in db
Image::create([
'user_id' => auth()->user()->id,
'post_id' => $post->id,
'position' => $position,
'filename' => $filename,
'extension' => $extension,
'src' => 'post_images',
'mime_type' => $file->getMimeType(),
'file_size' => $file->getSize(),
]);
}
public function saveMedia($post) {
// Make sure user owns post
abort_unless($post->user_id == auth()->user()->id, 403);
// Set default position
$position = 1;
// Save each image
foreach ($this->images as $file) {
$this->saveImage($file, $post, $position);
// Increment position for next image
$position++;
}
}
}
For sorting items in Livewire I would use https://github.com/livewire/sortable.
Sortable is very easy to use.
For filepond if the original image should be used again later I would save that image as well with a relation to the edited version.

Cannot upload images laravel

I uploaded my files on my server, but I cannot change my root folder to public via the hosting company, so I moved the files from public to the httpdocs directory, but I have now an issue with uploading images, i made this path
$this->validate($request, [
'image' => 'image|nullable|max:1999'
]);
if ($request->hasFile('image')) {
$filenameWithExt = $request->file('image')->getClientOriginalExtension();
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
$extension = $request->file('image')->getClientOriginalExtension();
$fileNameToStore = $filename . '_' . Carbon::today()->toDateString() . '.' . $extension;
$request->file('image')->storeAs('/../Supplier/public/images', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
And when I submit my form I get this error
Path is outside of the defined root, path:
And to show the image after upload i have this code in html
<td><a download="retourmelding_{{$retour->firmaname}}" href="/storage/images/{{$retour->images}}" title="Foto">
<img alt="Foto" src="/storage/images/{{$retour->images}}">
</a></td>
But locally it works perfectly
Please try it:
$request->file('image')->storeAs(storage_path('images'), $fileNameToStore);
The directory definition you have made is incorrect.
../httpdocs/storage/images/ mean is [laravel directory]/httpdocs/storage/images/
Use helpers for directory defination: Helpers - Laravel
I would change the disk in "config \ filesystems.php" and put something like this:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
You can do that using the below code:
In config/filesystem.php
'my_file' => [
'driver' => 'local',
'root' => storage_path(),
],
In controller
$fileNameToStore = $request->file('myfile');
$name = $fileNameToStore->getClientOriginalName();
Storage::disk('my_file')->PutFileAs('images', $fileNameToStore, $name);
For retrieving the image in view file using the route. Because of directly can not access the storage/images folder.
You need to create a new function in the controller.
use Auth, Storage, File, Response;
public function displayImage($filename)
{
$path = storage_path('images/' . $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;
}
New Route add
Route::get('image/{filename}', 'YOURCONTROLLER#displayImage')->name('image.displayImage');
View( Retrieving image)
<img src="{{ route('image.displayImage',$image) }}" alt="" title="">

Why the picture value is not uploaded into DB from laravel form?

I have a form for adding new profile. In the form, there is a file input field to enable user upload his/her picture to be saved in DB as its pathname to image saved in folder server.
However, my testing shows that it doesn't detected input field has image and doesn't go into if ($request->hasFile('image')) statement loop. This is the form field for file upload.
<div class="form-group">
<div class="row">
<label for="gambar" class="col-md-3 control-label">Gambar (Saiz gambar 250x300 pixels)</label>
<div class="col-md-7">
{!! Form::file('image', array('class' => 'form-control')) !!}
</div>
</div>
</div>
This is the controller function to upload the image:
// **************************
if ($request->hasFile('image')) {
$image = $request->input('image');
$photo = $request->file('image')->getClientOriginalExtension();
$destination = public_path() . '/images/';
$request->file('image')->move($destination, $photo);
$data = ['name' => $request->nama,
'No' => $request->no_id,
'nokp' => $request->no_kp,
'dd' => $dd,
'yy' => $request->yy,
'SectionID' => $request->sections,
'CategoryID' => $request->kategori,
'OperasiID' => $request->pangkat,
'AgamaID' => $request->agama,
'JantinaID' => $request->jantina,
'BangsaID' => $request->bangsa,
'nolahir' => $request->no_surat_lahir,
'kumdarah' => $request->kumdarah,
'Picture' => $request->$photo,
];
$itemregistrations = DB::table('itemregistrations')->insert($data);
if($itemregistrations)
return redirect('profil');
else
return redirect()->back()->withInput();
} else {
$data = ['name' => $request->nama,
'No' => $request->no_id,
'nokp' => $request->no_kp,
'dd' => $dd,
'yy' => $requestyy,
'SectionID' => $request->sections,
'CategoryID' => $request->kategori,
'OperasiID' => $request->pangkat,
'AgamaID' => $request->agama,
'JantinaID' => $request->jantina,
'BangsaID' => $request->bangsa,
'nolahir' => $request->no_surat_lahir,
'kumdarah' => $request->kumdarah,
// 'Picture' => $request->$filePath,
];
$itemregistrations = DB::table('itemregistrations')->insert($data);
if($itemregistrations)
return redirect('profil');
else
return redirect()->back()->withInput();
}
In your data array you target 'Picture' => $request->$photo, and not 'Picture' => $photo,
Also it looks like you are pulling just the extension look at the list below of some commands to use and when:
//Display File Name
$file->getClientOriginalName();
//Display File Extension
$file->getClientOriginalExtension();
//Display File Real Path
$file->getRealPath();
//Display File Size
$file->getSize();
//Display File Mime Type
$file->getMimeType();
To Uplaod a file do
$file = $request->file('image');
$file->move($destination, $file->getClientOriginalName());
Make sure your form have following attribute
enctype="multipart/form-data"
and use following laravel file upload code
if ($request->hasFile('image')) {
$is_file = true;
$file_name = $input['image'] = time() . '.' . $request->image->getClientOriginalExtension();
$request->image->move(base_path() . '/assets/images/users/', $input['image']);
}

Can't show the image in slider with yii2

I have code to show view like this
<div class="col-md-10">
<div class="col-md-4">
<?php
$items = [];
foreach ($team->gallery as $item){
$items[] = [
'content' => '<img style="width:300px;" src="'.$item->filepath.'"/>',
'caption' => '<h4>'.$item->name.'</h4><p>'.$item->description.'</p>',
];
}
echo Carousel::widget([
'items' => $items,
]);
?>
</div>
and model for get galery like this
public function getLeague(){
return $this->hasOne(Leagues::className(), ['id' => 'league_id']);
}
public function getGallery(){
return $this->hasMany(TeamGalleries::className(), ['team_id' => 'id']);
}
but i can't get the filepath in my databases therefore i can't show my picture in my website, how to solved this problem?
i use yii2 and the folder upload for my picture is in web folder in yii2 basic
If your images are within the web folder you can easily use the Yii aliases, which have one entry for this folder: #web.
// Replace this
'<img style="width:300px;" src="'.$item->filepath.'"/>'
// with
'<img style="width:300px;" src="' . Yii::getAlias('#web') . '/' . $item->filepath . '"/>'
Further information about aliases in the guide.

Resources