How to display multiple images that stored as array in laravel? - laravel

please help me to display image that stored as array in database
my controller:
( filename is my image column name in database)
public function store(Request $request)
{
$this->validate($request, [
'filename' => 'required',
'filename.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
// Start multiple image upload code
if($request->hasfile('filename'))
{
foreach($request->file('filename') as $image)
{
$name=$image->getClientOriginalName();
$image->move(public_path().'/images/', $name);
$data[] = $name;
}
}
// End multiple image upload code
$houses= new House();
$houses->division = $request->input('division');
$houses->city = $request->input('city');
$houses->area = $request->input('area');
$houses->owner_name = $request->input('owner_name');
$houses->house_name = $request->input('house_name');
$houses->type = $request->input('type');
$houses->from = $request->input('from');
$houses->rent = $request->input('rent');
$houses->phone = $request->input('phone');
$houses->address = $request->input('address');
$houses->description = $request->input('description');
$houses->filename=json_encode($data); **// This for image upload**
$houses->save();
return back()->with('success', 'Your House has been successfully');
}
image column

First array cast the filename column in your model. For more: Array & JSON Casting
protected $casts = [
'filename' => 'array',
];
After that, whenever you fetch filename from House model, laravel will automatically convert the json data to array. Loop through the array and display the images.
$house = House::find(1);
foreach($house->filename as $filename) {
echo public_path().'/images/', $filename;
}

If you want to retrieve then display the images stored as an array what I'd suggest is casting the filename attribute to json/array in the model.
You can do that in your House model like this:
class House extends Model
{
protected $casts = [
'filename' => 'array',
];
}
To display it in a view you can loop through the casted array:
#foreach($house->filename as $image)
<img src="{{ url('link/to/assets/') . $image }}"
#endforeach
See more in the docs about casting here:
https://laravel.com/docs/5.7/eloquent-mutators#array-and-json-casting
A side point on image uploads, you may want to give uploaded files a unique name rather than using the user's filename so there's no conflict if a user uploads a document with the same name twice.
Laravel handles this all for you in the store() method seen here: https://laravel.com/docs/5.7/requests#storing-uploaded-files. You can create your own names if preferred using storeAs().

Related

Laravel Backpack Image Upload Issue

I m trying to upload images in Laravel Backpack. I had added field in my Controller:
$this->crud->addfield([
'label' => "Logo",
'name' => "logo",
'type' => 'image',
'upload'=> true,
'crop' => true, // set to true to allow cropping, false to disable
'aspect_ratio' => 1, // ommit or set to 0 to allow any aspect ratio
//'disk' => 'public', // in case you need to show images from a different disk
'prefix' => 'uploads/college/' // in case your db value is only the file name (no path), you can use this to prepend your path to the image src (in HTML), before it's shown to the user;
]);
Here is my Model:
protected $fillable = ['name','description','logo','location','establised_at'];
// protected $hidden = [];
// protected $dates = [];
public function setImageAttribute($value)
{
$attribute_name = "logo";
$disk = "public";
$destination_path = "/uploads";
// if the image was erased
if ($value==null) {
// delete the image from disk
\Storage::disk($disk)->delete($this->{$attribute_name});
// set null in the database column
$this->attributes[$attribute_name] = null;
}
// if a base64 was sent, store it in the db
if (starts_with($value, 'data:image'))
{
// 0. Make the image
$image = \Image::make($value)->encode('jpg', 90);
// 1. Generate a filename.
$filename = md5($value.time()).'.jpg';
// 2. Store the image on disk.
\Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
// 3. Save the path to the database
$this->attributes[$attribute_name] = $destination_path.'/'.$filename;
}
}
It's trying to save the base64 data in database but I don't want to do so.
It would be great help if anyone solve it. Thank You!
I've tried the code shown in docs and it works.
I think your problem is the mutator function name. To define a mutator you have to define a method in your model like set{attribute_name}Attribute.
In your case, your mutator function is setImageAttribute then it is looking for an attribute called image.
I think that if you change this code:
public function setImageAttribute($value)
{
with this
public function setLogoAttribute($value)
{
it will work
you miss a step:
like in doc
\Storage::disk($disk)->delete($this->{$attribute_name});
$public_destination_path = Str::replaceFirst('public/', '', $destination_path);
$this->attributes[$attribute_name] = $public_destination_path.'/'.$filename;

Vue / Laravel: How to validate files uploaded from the frontend?

I have an image uploader on my Vue app that takes multiple files. I want to ensure they are images and of a certain size and if not, obviously don't upload the files and have the frontend display the error. Right now, the route it hits in the controller loos like this:
public function uploadAssets(UploadAssetsFormRequest $request)
{
if ($request->hasFile('file')) {
$files = $request->file('file');
$stack = [];
foreach ($files as $file) {
$fileName = Storage::put('/check/', file_get_contents($file->getRealPath()), ['visibility' => 'public']);
array_push($stack, $fileName);
}
return response()->json($stack);
}
}
My Form Request is below and has the validation but I don't know how to apply that in the controller.
UploadAssetsFormRequest
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Foundation\Http\FormRequest;
class UploadAssetsFormRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'files.*' => 'required|image|max:1000',
];
}
public function messages()
{
return [
'files.*.max' => 'The image is too large',
'files.*.image' => 'Only image files are allowed.',
];
}
}
You need to check files extension :
$extension = $file->extension();
$allowed_file_types = ['jpg','png','gif'];
if (in_array($extension, $allowed_file_types)){
//do upload
}else{
Continue;
}
for file sizes check this thread
You can use laravel image validation
$this->validate ($input, [
'files.*.image' => 'image|max:200',
]):
Note: max(size) is in Kilobytes
You can also use dimension rule
$this->validate ($input, [
'files.*.image' => 'dimensions:min_width=100,min_height=200'
]):
Laravel Image Validation
Laravel Image Dimensions Validation
You can set the following rule in your validation -
'file' => 'required|max:100|mimes:jpg,png,bmp' // 100kb, mimes must have image extensions

Deleting an Item from array of a table column in Laravel

There is a Posts table that has a column named images. in images I store data as JSON array as:
["p1.jpg", "p2.jpg","p4.jpg","p9.jpg","p11.jpg", "p12.jpg","p13.jpg", "p14.jpg"];
I want to delete one of these images by ajax. I send the id and image by ajax and get that id and image in the controller correctly:
public function remove() {
$imgs = Image::where('id', request()->id)->pluck('images');
return $imgs;
}
reults in console:
[Array(8)]
0: (8) ["p1.jpg", "p2.jpg", "p4.jpg", "p9.jpg", "p11.jpg", "p12.jpg", "p13.jpg", "p14.jpg"]
length: 1
__proto__: Array(0)
also, I get the image name by request()->img from ajax.
$image = request()->img; => p12.jpg
How I can delete the $image from $images array?
First You may cast images attr to array in your Image model
//App\Image
protected $casts = [
'images' => 'array'
];
Then in your remove function :
public function remove() {
if(request()->id && request()->img) {
$imgModel = Image::findOrFail(request()->id);
$imgs = $imgModel->images;
// find request()->img position inside imgs array
$position = array_search(request()->img, $imgs);
// delete request()->img
unset($imgs[$position]);
$imgModel->images = array_values($imgs);
$imgModel->save();
}
}

Laravel: Database is not storing my image but showing me only array

I am new to Laravel. I have been trying to save an image to the database. Here is my controller method that I am trying for storing the image
public function store(Request $request){
//validation for form
$validate= $request->validate([
'name' => 'required|min:2|max:140',
'position' => 'required|min:2|max:140',
'salary' => 'required|min:2|max:140',
'joining_date' => ''
]);
//saving form
if($validate){
$employee=new Employee;
$employee->name =$request->input('name');
$employee->company_name =$request->input('company_name');
$employee->position =$request->input('position');
$employee->salary =$request->input('salary');
$employee->joining_date =$request->input('joining_date');
$employee->user_id= auth()->user()->id;
//image saveing method
if($request->hasFile('image')){
$image= $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
Employee::make($image)->resize(300, 300)->save( public_path('/employee/images/' . $filename ) );
$employee->image= $filename;
}else{
return $request;
$employee->image= '';
};
$employee->save();
//redirecting to Employee list
return redirect('/employee/details')->with('success','Employee Added');
}
I could save the form while there was no image and redirect it to the details page. but now when I try with the image, instead of saving it and redirecting to the details route, it returns me to the array of row of database like this:
{
"_token": "FPHm9AKuEbRlqQnSgHhjPnCEKidi2xr0usgp7RoW",
"name": "askfjlk",
"company_name": "laksjsflkj",
"position": "lkasjfkl",
"salary": "35454",
"joining_date": "4654-05-06",
"image": "testing.png"
}
What did I do wrong here? please help me out this newb.
You are returning $request object and Laravel does automatic JSON response.
if ($request->hasFile('image')){
// image storing logic which obviously is never started because expression above is false
} else {
return $request; // There is your problem
$employee->image= '';
};
You need to check why you are getting false on $request->hasFile('image').
Also, one tip because you are new to Laravel:
// When you are accessing to $request object you can use dynamic propertes:
$employee->company_name = $request->input('company_name');
// is the same as
$employee->company_name = $request->company_name;
You can check it there: Laravel docs in the section: Retrieving Input Via Dynamic Properties

yii2 get getter's value in active query request (using asArray())

I have the next code:
$fixed_events = EventMain::find()
->select(["id", "title", "files"])
//->joinWith(['files'])
//->with(['files'])
->asArray()
->all();
How can i get array with "files" value, taking into account, that the "files" is modle's getter like
public function getFiles()
{
return (json_decode($this->all_files, true)) ?: [];
}
Since files is not a relation with EventMain table, I guess the easiest approach would be handle the data and convert with ArrayHelper after coming from db:
<?php
use yii\helpers\ArrayHelper;
$models = EventMain::find()->select(['id', 'title'])->all();
$array = ArrayHelper::toArray($models, [
'app\models\EventMain' => ['id', 'title','files']
]);
var_dump($array);
?>

Resources