file input multiple file selection not working - php

when i die/dump $files i can only see one file in the request when am expecting to see all the files selected. when i die/dump $name in the foreach loop nothing is happening. I need to see all the selected images in the request.
blade create
<form action="/p" enctype="multipart/form-data" method="post" files = "true">
#csrf
<label for="image" class="col-md-4 col-form-label text-md-right">{{ __(' post image') }}</label>
<input type="file", class="form-control-file" id ="image" multiple = "multiple" name="image">
#error('image')
<div class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong> </div>
#enderror
</form>
postcontroller
public function store( Request $request )
{` $request->request->add(['user_id' => $user], ); // Here a request is given a varible either for the admin or user
$data = request()->validate([
'user_id' => 'required',
'about' => 'required',
'category' => '',
'expire_date' => '',
]); `if (Auth::guard('web')->check())
{
$user = Auth::user();
$post = new Post();
/*$post = $user->posts()->create([
'about' => $data['about'],
'category' => $data['category'],
'expire_date' => $data['expire_date'],
]);*/
if($request->hasFile('image'))
{
$files = $request->file('image');
foreach($files as $file)
{
$name = time().'-'.$file->getClientOriginalName();
$name = str_replace('','-',$name);
$file->move('images',$name);
//$post->images->create(['image' => $name ]);
}
} `
$user = Auth::guard('web')->id() ;
// return redirect()->route('home',['user'=>$user]);
}
}

For multiple input, in your html you need to pass it as an array for the name attribute. Change name="image" to name=image[], i.e :
<input type="text" name="image[]" />
This way php will receive an array of image's.

The $casts property on your model provides a convenient method of converting attributes to common data types. The $casts property should be an array where the key is the name of the attribute being cast and the value is the type you wish to cast the column to.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $casts = [
'image' => 'array',
];
}

Related

Laravel Edit removes uploaded file

I am creating a Laravel crud. in here i have a DB table called:
File:
'title','description_short','description_long,'file','language'
the problem lays in the 'file' column. here i can upload files like word and excel. but whenever i edit a row with a file attached. the file gets removed if i don't upload A or THE file again.
edit.blade:
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h1 class="display-3"> {{('Editing files')}}</h1>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
<br />
#endif
#if(empty($fileEdit))
<div>{{('Choose file to edit')}}</div>
#else
<form method="post" action="{{ route('admin.file.update', $fileEdit->id) }}">
#method('PUT')
#csrf
<div class="form-group">
<label for="name">{{('title')}}</label>
<input type="text" class="form-control" name="title" value="{{ $fileEdit->title }}" />
</div>
<div class="form-group">
<label for="name"> {{('Short description')}}</label>
<input type="text" class="form-control" name="description_short" value="{{ $fileEdit->description_short }}" />
</div>
<div class="form-group">
<label for="name"> {{('Long description')}}</label>
<input type="text" class="form-control" name="description_long" value="{{ $fileEdit->description_long }}" />
</div>
<div class="form-group">
<label for="name"> {{('file')}}</label>
<input type="file" class="form-control" name="file" value="{{ $fileEdit->file }}" />
</div>
<div class="form-group">
<label for="name">{{('language')}}</label>
<select name="language_id" class="form-control">
#foreach($languages as $language)
<option value=" {{$language->id}}">{{$language->name}}</option>
#endforeach
</select>
</div>
<button type="submit" class="btn btn-primary">Update</button>
</form>
#endif
</div>
</div>
controller:
<?php
namespace App\Http\Controllers\admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\File;
use App\Models\Language;
class FileController extends Controller
{
public function index()
{
$files = File::with('language')->get();
$languages = Language::all();
return view('admin.file.index', compact('files', 'languages'));
}
public function create()
{
//
}
public function store(Request $request)
{
$request->validate([
'title'=>'required',
'description_short'=>'',
'description_long'=>'',
'file'=>'',
'language_id'=> [
'required', 'exists:language,id'
],
]);
$file = new File([
'title'=> $request->get('title'),
'description_short'=> $request->get('description_short'),
'description_long'=> $request->get('description_long'),
'file'=>$request->get('file'),
'language_id'=> $request->language_id,
]);
$file->save();
return back();
}
public function show($id)
{
//
}
public function edit($id)
{
$files = File::all();
$fileEdit = File::find($id);
$languages = Language::all();
return view('admin.file.index', compact('files', 'fileEdit', 'languages'));
}
public function update(Request $request, $id)
{
$request->validate([
'title'=>'required',
'description_short'=>'',
'description_long'=>'',
'file'=>'',
'language_id'=> [
'required', 'exists:language,id'
],
]);
$fileData = [
'title'=> $request->title,
'description_short'=> $request->description_short,
'description_long'=> $request->description_long,
'file'=>$request->file,
'language_id'=> $request->language_id,
];
File::whereId($id)->update($fileData);
return redirect()->route('admin.file.index');
}
public function destroy($id)
{
$file = File::find($id);
$file->delete();
return redirect()->route('admin.file.index');
}
}
File model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
use HasFactory;
public function language(){
return $this->belongsTo(Language::class);
}
protected $table = 'file';
protected $fillable = [
'title',
'description_short',
'description_long',
'file',
'language_id',
'user_id',
];
}
for security reasons, you can't set value of input type file. so
<input type="file" class="form-control" name="file" value="{{ $fileEdit->file }}" />
is not adding the old file in the input. what you can do is checking if user added any file in controller.
<input type="file" class="form-control" name="file" />
in controller
$fileData = [
'title' => $request->title,
'description_short' => $request->description_short,
'description_long' => $request->description_long,
'language_id' => $request->language_id,
];
if ($request->get('file')) {
$fileData['file'] = $request->file;
}
File::whereId($id)->update($fileData);
if you leave the validation field blank it may take the input as empty there for use bail which will not validation but the input should be empty. you will update with a data you are passing to validator.
$request->validate([
'title'=>'required',
'description_short'=>'bail',
'description_long'=>'bail',
'file'=>'bail',
'language_id'=> [
'required', 'exists:language,id'
],
]);
$fileData = [
'title'=> $request->title,
'description_short'=> $request->description_short,
'description_long'=> $request->description_long,
'file'=>$request->file,
'language_id'=> $request->language_id,
];
File::whereId($id)->update($fileData);
make sure you have added file on fillable properties on File model
Try this
public function update(Request $request, $id)
{
$request->validate([
'title'=>'required',
'description_short'=>'',
'description_long'=>'',
'file'=>'',
'language_id'=> [
'required', 'exists:language,id'
],
]);
$fileData = [
'title'=> $request->title,
'description_short'=> $request->description_short,
'description_long'=> $request->description_long,
'language_id'=> $request->language_id,
];
if (isset ($request->file)) {
$fileData['file'] = $request->file
}
File::whereId($id)->update($fileData);
return redirect()->route('admin.file.index');
}

Uploading image from input field and still getting validation error saying that field is required

Route Code:
Route::group(['middleware' => 'auth', 'prefix' => 'admin'], function(){
Route::resource('gallery', GalleryController::class);
});
The Form I'm Using to Upload the File:
<form action="{{ route('gallery.store') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="input-group mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" name="gallery_img" id="inputGroupFile01">
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
</div>
#error('gal_img')
<span class="text-danger">{{ $message }}</span>
#enderror
<div class="input-group-append">
<div class="col-sm-10" style="padding-left: 1px;">
<button type="submit" class="btn btn-dark">Save</button>
</div>
</div>
Controller Code:
public function store(GalleryRequests $request)
{
$gal_img = $request->file('gallery_img');
$gal_file = date('YmdHi').$gal_img->getClientOriginalName();
$gal_img->move(public_path('upload/gallery'), $gal_file);
$save_path = 'upload/gallery/'.$gal_file;
Gallery::insert([
'gal_img' => $save_path
]);
$notification = array(
'message' => 'Slider Inserted Successfully',
'alert-type' => 'success'
);
return redirect()->back()->with($notification);
}
Request file validation:
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'gal_img' => 'required'
];
}
public function messages(){
return [
'gal_img.required' => 'Please Select an Image First',
];
}
The error I get when trying to save after selecting an Image:
Trying to figure out what I've done wrong for hours and am so frustrated right now, please help me to resolve this issue.
Thanks in advance.
Field in form is named gallery_img so that name has to be checked:
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'gallery_img' => 'required'
];
}
public function messages()
{
return [
'gallery_img.required' => 'Please Select an Image First',
];
}

How do I redirect to another page after form submission in Laravel

form
When i submit the form it redirects back to the form itself, can anyone help me?
<form action="/jisajili" method="POST">
#csrf
<div class="card-panel z-depth-5">
<h5 class="center red-text">Jiunge Nasi</h5>
<div class="input-field">
<i class="material-icons prefix">account_circle</i>
<input type="text" name="username" class="validate">
<label>Jina lako</label>
</div>
<div class="input-field">
<i class="material-icons prefix">phone</i>
<input type="number" name="phone" class="validate">
<label>Nambari ya simu</label>
</div>
....
</p>
<input type="submit" name="submit" value="Jiunge" class="btn left col s12 red">
Controller
class registration extends Controller{
public function create(){
return view('jisajili.jiunge');
}
public function store(Request $request){
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$cpassword = $request -> input('cpassword');
$reg->save();
$validated = $request->validate([
'name' => 'required|unique:posts|max:10',
'body' => 'required',
]);
return redirect('home');
}
}
What I would do is first check for the data requirements before you add the object to the database. Also I would add the columns of the models into the Model file to use the Object::create function with an array parameter.
I recomment to use routing in your blade file. I noticed you used action="/route". What you want to do is naming your routes with ->name('route_name') in the route files. To use them in your blade files with the global route function route="{{ route('route_name') }}".
<?php
class PostController extends Controller
{
public function index()
{
return view('post.create');
}
public function store(\Illuminate\Http\Request $request)
{
$validator = Validator::make(
$request->all(),
[
'name' => 'required|unique:posts|max:10',
'body' => 'required'
]
);
// Go back with errors when errors found
if ($validator->fails()) {
redirect()->back()->with($validator);
}
Post::create(
[
'name' => $request->get('name'),
'body' => $request->get('body')
]
);
return redirect()
->to(route('home'))
->with('message', 'The post has been added successfully!');
}
}
What you can do after this is adding custom errors into the controller or add them into your blade file. You can find more about this in the documentation of Laravel.
it redirects you back because of validation error.
change password confirmation name from cpassword into password_confirmation as mentioned in laravel docs
https://laravel.com/docs/7.x/validation#rule-confirmed
update your controller into:
public function store(Request $request){
$validated = $request->validate([
'username' => 'required',
'phone' => 'required',
'email' => 'required',
'password' => 'required|confirmed'
]);
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$reg->save();
return redirect('home');
}
in your blade add the following to display validation errors:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

Laravel file upload without changing name

I want to upload a files to my laravel project. But I recognise that laravel randomly change my file name. How do I upload files to laravel without changing it's name. Also somehow my validation are not working. I just got redirected without any messages.
this are my blade
//show errors
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
/ul>
</div>
#endif
// forms
<form action="{{ route('designers.store') }}" method="post" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group d-flex flex-column">
<label for="exampleInputFile">File input</label>
<input type="file" name="files[]" multiple>
</div>
<button type="submit">Submit</button>
</form>
this are my controller
$data = $request->validate([
'project' => 'required|numeric',
'totalItem' => 'required|numeric',
'files' => 'file',
]);
if ($request->hasFile('files')) {
$allowedfileExtension=['pdf','jpg','png','docx','png','xlsx'];
$files = $request->file('files');
foreach ($files as $key => $value) {
$filename = $value->getClientOriginalName();
$extention = $value->getClientOriginalExtension();
$check = in_array($extention,$allowedfileExtension);
if ($check) {
File::create([
'name' => $value->store('designers','public'),
'type' => 'designer',
'project_id' => $data['project'],
'user_id' => Auth::user()->id,
]);
}
}
}
You can change your controller to this:
use Illuminate\Support\Facades\Storage;
function yourFunction(){
$this->validate($request,[
'project' => 'required|numeric',
'totalItem' => 'required|numeric',
'files' => 'nullable|array|file|mimes:pdf,jpg,png,docx,xlsx' //This validates file and MIME type. Also if it is not required, it should perhaps be nullable.
]);
if($request->hasFile('files'){
$files = $request->file('files');
foreach($files as $file){
$filename = $file->getClientOriginalName();
Storage::disk('local')->put($filename, file_get_contents($file)); //This stores your file.
}
}
//Save stuff to DB here
}
Official doc on file storage: https://laravel.com/docs/5.8/filesystem
Official doc on Validation of MIME: https://laravel.com/docs/5.8/validation#rule-mimes

Laravel 5.8 PDF upload

for my website I need a form which includes a file upload for PDF files, but I'm new to these and don't really know how to do it.
This is what I got so far, but keep getting:
"Too few arguments to function App\Http\Controllers\FileController::create(), 0 passed and exactly 1 expected"
Controller:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Payment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
public function index(){
$users = User::all();
return view('fileupload.create', compact('users'));
}
protected function create(array $data)
{
$request = app('request');
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $file['filename']->getClientOriginalExtension();
Storage::make($file)->save( public_path('/storage/loonstrookjes/' . $filename) );
dd($filename);
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $data['employee'],
]);
return route('fileupload.create');
}
}
Model User:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Kyslik\ColumnSortable\Sortable;
class User extends Authenticatable
{
use Notifiable;
use Sortable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table = 'users';
protected $fillable = [
'username', 'first_name', 'last_name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Model Payment:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
{
protected $table = 'payment_list';
protected $fillable = [
'user_id', 'file_name', 'file_path'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'id', 'file_name', 'file_path'
];
}
View:
#extends('layouts.master')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Loonstrook uploaden') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('create') }}" enctype="multipart/form-data">
#csrf
<div class="form-group row">
<label for="filename" class="col-md-4 col-form-label text-md-right">{{ __('Bestandsnaam') }}</label>
<div class="col-md-6">
<input id="filename" type="text" class="form-control{{ $errors->has('filename') ? ' is-invalid' : '' }}" name="filename" value="{{ old('filename') }}" required autofocus>
#if ($errors->has('filename'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('filename') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group row">
<label for="file" class="col-md-4 col-form-label text-md-right">{{ __('Bestand') }}</label>
<div class="col-md-6">
<input id="file" type="file" class="form-control" name="file">
</div>
</div>
<div class="form-group row">
<label for="usertype" class="col-md-4 col-form-label text-md-right">{{ __('Werknemer:') }}</label>
<div class="col-md-6">
<select class="form-control" name="type">
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->first_name}} {{$user->last_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Uploaden') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
These are my routes:
Route::get('/create', 'FileController#index')->name('create');
Route::post('/create', 'FileController#create');
I hope someone can help me find out what's wrong or a better way to do this. Thank you in advance!!
EDIT:
Your answers have helped me quite a bit, but now I'm facing another issue...
The controller now looks like this:
<?php
namespace App\Http\Controllers;
use App\User;
use App\Payment;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
UploadedFile::getMaxFilesize();
class FileController extends Controller
{
public function index(){
$users = User::all();
return view('fileupload.create', compact('users'));
}
protected function validator(array $data)
{
return Validator::make($data, [
'filename' => ['required', 'string', 'max:255'],
'file' => ['required', 'file'],
'user_id' => ['required'],
]);
}
protected function create(Request $request)
{
$request = app('request');
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $request->input('filename');
$file = $filename . '.' . $file->getClientOriginalExtension();
$file_path = storage_path('/loonstrookjes');
Storage::disk('local')->putFile($file_path, new File($request->file), $file);
//$path = $request->file('file')->store( storage_path('/storage/loonstrookjes/'));
//$path = Storage::putFile(storage_path('/loonstrookjes/'), $filename);
//dd($upload);
//return $put;
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $request['user'],
]);
return route('fileupload.create');
}
}
But I'm getting a new error, this time it's:
Call to undefined method Illuminate\Support\Facades\File::hashName()
Any ideas??
Your problem is you have a parameter in your method create(array $data), but you are posting the form using only {{ route('create') }}. Here you are calling the method by this route without passing the required parameter as you defined it.
Basically, a form post method can accept the requested values by this
protected function create(Request $request)
Because you already used Request as a trait.
So, by this, you can get the requested field value from your form. And you don't have to use $request = app('request'); since you already have it on the parameter variable $request.
In case you want to know
Variables are passed from frontend (view)
to the backend (route) by using {{ route('update', $the_variable) }}.
By this, you can have $the_variable after the last / of your route.
Hope this helps.
Route:
Route::resource('File','FileController');
Controller changes:
public function store(Request $request)
{
if($request->hasfile('file')){
$file = $request->file('file');
$filename = $file['filename']->getClientOriginalExtension();
Storage::make($file)->save( public_path('/storage/loonstrookjes/' . $filename) );
}
return Payment::create([
'file_name' => $filename,
'file_path' => '/storage/loonstrookjes/',
'user_id' => $request->type
]);
return route('fileupload.create');
}
}
View Changes:
form action="{{ route('File.store') }}"

Categories