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');
}
Related
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',
];
}
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
I'm working on Laravel project and i would like to know:
how to insert data to my multiple related tables ?
How can we insert author id in the author_type_id field of the Author table?
How to store author_id in post?
So idon't know how to insert related models using a form. thanks for your help :)
my models
//Post model
class Post extends Model
{
//
protected $fillable = [
'post_type_id','author_id','author_type_id','article'
];
public function posttype()
{
return $this->belongsTo(Posttype::class);
}
public function author()
{
return $this->belongsTo(Author::class);
}
public function authortype()
{
return $this->belongsTo(Authortype::class);
}
}
//Posttype model
class Posttype extends Model
{
//
protected $fillable = [
'post_type'
];
public function posts()
{
return $this->hasMany(Post::class);
}
}
//author model
class Author extends Model
{
//
protected $fillable = [
'author_name','author_first_name','author_type_id'
];
public function posts()
{
return $this->belongsToMany(Post::class);
}
public function authortype()
{
return $this->belongsTo(Authortype::class);
}
}
//Authortype model
class Authortype extends Model
{
//
protected $fillable = [
'author_type '
];
public function author()
{
return $this->hasMany(Author::class);
}
public function posts()
{
return $this->hasMany(Post::class);
}
}
// PostsController Contoller
class PostsController extends Controller
{
public function index()
{
return view('index')->with('posts',Post::all());
}
public function create()
{
return view('create')->with('posttypes',$posttypes)
->with('authors',$authors)
->with('authortypes',$authortypes);
}
public function store(Request $request)
{
$this->validate($request,[
"post_type_id" => "required",
"author_id" => "required",
"author_type_id" => "required",
"article" => "required"
]);
//How can we insert author id in the author_type_id field of the Author table?
$post = Post::create([
"post_type_id" => $request->post_type_id,
"author_id" => $request->author_id,
"author_type_id" => $request->author_type_id,
"article" => $request->article,
]);
return redirect()->back();
}
}
//create post blade
#section('content')
<div class="container">
<form action="{{route('store')}}" method="POST" enctype="multipart/form-data">
{{ csrf_field()}}
<div class="form-group">
<label for="posttype">Post Type</label>
<select class="form-control" id="posttype" name="post_type_id">
#foreach ($posttypes as $posttype)
<option value="{{$posttype->id}}">{{$posttype->post_type}}</option>
#endforeach
</select>
</div>
//author type for author model (author_type_id)
<div class="form-group">
<label for="authortype">Author Type</label>
<select class="form-control" id="authortype" name="author_type_id">
#foreach ($authortypes as $authortype)
<option value="{{$authortype->id}}">{{$authortype->author_type}}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label for="author_name">Author Name</label>
<input type="text" class="form-control" name="author_name" placeholder="your name">
</div>
<div class="form-group">
<label for="author_first_name">Author First Name</label>
<input type="text" class="form-control" name="author_first_name" placeholder="your first name">
</div>
//How to store author_id in post
<div class="form-group">
<label for="content">article</label>
<textarea class="form-control" name="article" rows="8" cols="8"></textarea>
</div>
<button type="submit" class="btn btn-primary">{{__('main.save')}}</button>
</form>
</div>
#endsection
I found solution, May this can help you in future.
$author = Author::create([
'author_type_id' => $request->author_id,
]);
$post = Post::create([
"post_type_id" => $request->post_type_id,
"author_id" => $author->id,
"author_type_id" => $request->author_type_id,
"article" => $request->article,
]);
Auther::create([
'author_type_id' => $request->author_id,
]);
I want to use input from a form in one view and print results into another view. I get the following error: Undefined variable: users Thanks in advance!
The form (in a view called 'dashboard') that I am using to get email address:
...
<div class="search">
<header><h3>Search Friend</h3></header>
<form action="{{ route('search.friend') }}" method="post">
<div class="form-group">
<input class="form-control" type="text" name="email" id="email" placeholder="Friend's email">
</div>
<button type="submit" class="btn btn-primary">Post</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
</div>
...
The route to send data from 'dashboard' to Controller:
Route::post('/searchfriend',[
'uses' => 'FriendController#getSearchFriend',
'as' => 'search.friend',
'middleware' => 'auth'
]);
The controller where I use the email to find user:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['$users' => $users]);
}
}
The route to send the result to a 'userlist' view:
Route::get('/userlist',[
'uses' => 'FriendController#getSearchFriend',
'as' => 'userlist',
'middleware' => 'auth'
]);
Finally, the 'userlist' view:
#extends('layouts.master')
#section('title')
Users
#endsection
#section('content')
<section class="row new-post">
<div class="col-md-6 col-md-offset-3">
<header><h3>Users</h3></header>
<div class="userlist">
<header><h2>Click to Add Friend</h2></header>
#foreach($users as $user)
Name: {{ $user->username }}
#endforeach
</div>
</div>
</section>
#endsection
Change:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['$users' => $users]);
}
}
to:
class FriendController extends Controller
{
public function getSearchFriend(Request $request)
{
$this->validate($request,[
'email' => 'required | email'
]);
$email = $request['email'];
$users = User::where('email',$email)->get();
return view('userlist',['users' => $users]);
}
}
You don't need the $ when passing the name of the variable to the view.
#Ryan J Field is correct. Also, you can pass the variable in many different ways. Such as -
return view('userlist')->with('users', $users);
Or,
return view('userlist', compact(users));
I'm on Laravel 5.4 and i'm trying to do a register page but data are not send in my databse... And i don't have any error.
Here is the controller : (Generate by Laravel)
namespace App\Http\Controllers\Auth;
use App\User;
use App\PostUser;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
protected $primaryKey = "id_biodiv_acteur";
protected $table = "acteur";
use RegistersUsers;
protected $redirectTo = '/pages/users';
public function __construct()
{
$this->middleware('guest');
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'surname' => 'string|max:255',
...
'picture' => 'image'
]);
}
protected function create(array $data)
{
return User::create([
'nom' => $data['name'],
'prenom' => $data['surname'],
...
'image' => $data['picture']
]);
}
}
My register.blade.php :
<div class="add-content container">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<h1>• Ajouter un utilisateur •</h1>
<div class="underline"></div>
<form action="{!! route('register') !!}" accept-charset="UTF-8" method="post" role="form">
{!! csrf_field() !!}
<div class="column-left">
<label class="has-float-label" for="name">
<input class="" type="text" placeholder="" name="name" required>
<span>Nom</span>
</label>
<label class="has-float-label" for="password">
<input class="" type="password" placeholder="" name="password" required>
<span>Mot de passe</span>
</label>
...
<label class="has-float-label" for="picture">
<input type="file" name="picture" multiple>
<span>Ajoutez des images</span>
</label>
</div>
<button type="submit" name="button">Enregistrer</button>
</form>
</div>
And a model i added to the controller (PostUser.php) :
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\Events\Registered;
class PostUser extends Model
{
public $timestamps = false;
protected $primaryKey = "id_acteur";
protected $table = "acteur";
protected $fillable = [
'nom',
'prenom',
...
'image'
];
}
Laravel created route for register :
$this->get('register', 'Auth\RegisterController#showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController#register');
But i haven't any function call register or showRegistrationForm in RegisterController
If route('register') goes to RegisterController#create method, you can get the user-entered data in the Request parameter of that method:
protected function create(\Illuminate\Http\Request $request)
{
return User::create([
'nom' => $request->name,
'prenom' => $request->surname,
...
'image' => $request->picture
]);
}
Also, as mentioned in comments, you need to change User to PostUser or vice-versa.