I am struggling to update data in the database with an edit form and couldn't find anything online that fits the logic of my setup.
I have a add button, delete button and an edit button. Adding and Deleting works but Editing does not update the data.
Any help would be appreciated as I have tried multiple methods with no success.
Thank you in advance.
View:
#extends('layouts.app')
#section('content')
<div class="container flex-center">
<div class="row col-md-8 flex-column">
<h1>Edit a link</h1>
#foreach ($links as $link)
<form action="{{ url('link/'.$link->id) }}" method="POST">
{!! csrf_field() !!}
#method('PUT')
#if ($errors->any())
<div class="alert alert-danger" role="alert">
Please fix the following errors
</div>
#endif
<h3 class="edit-link-title">{{ $link->title }}</h3>
{!! csrf_field() !!}
<div class="form-group{{ $errors->has('title') ? ' has-error' : '' }}">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" placeholder="Title" value="{{ $link->title }}">
#if($errors->has('title'))
<span class="help-block">{{ $errors->first('title') }}</span>
#endif
</div>
<div class="form-group{{ $errors->has('url') ? ' has-error' : '' }}">
<label for="url">Url</label>
<input type="text" class="form-control" id="url" name="url" placeholder="URL" value="{{ $link->url }}">
#if($errors->has('url'))
<span class="help-block">{{ $errors->first('url') }}</span>
#endif
</div>
<div class="form-group{{ $errors->has('description') ? ' has-error' : '' }}">
<label for="description">Description</label>
<textarea class="form-control" id="description" name="description" placeholder="description">{{ $link->description }}</textarea>
#if($errors->has('description'))
<span class="help-block">{{ $errors->first('description') }}</span>
#endif
#endforeach
</div>
<button type="submit" class="btn btn-default submit-btn">Submit</button>
</form>
</div>
</div>
#endsection
web/route controller:
use Illuminate\Http\Request;
Route::post('/submit', function (Request $request) {
$data = $request->validate([
'title' => 'required|max:255',
'url' => 'required|url|max:255',
'description' => 'required|max:255',
]);
$link = tap(new App\Link($data))->save();
return redirect('/');
});
use App\Link;
Route::delete('/link/{link}', function (Link $link) {
// Link::destroy($link);
$link->delete();
return redirect('/');
});
Route::PUT('/link/{link}', function (Link $link) {
$link->update();
return redirect('/');
});
As a design pattern, it's often recommended to separate your controller from the routes. The reason your edit is not updating is that you're not providing the model with the data from the request:-
Route::PUT('/link/{link}', function (Request $request, Link $link) {
$request->validate([
'title' => 'required|max:255',
'url' => 'required|url|max:255',
'description' => 'required|max:255',
]);
$link->update($request->all());
return redirect('/');
});
In a controller, you could abstract away the validation logic to a validation helper function to avoid duplicating code.
Good luck!
Related
I am working with Laravel 5.2 and developing project management app. In My application I have project created form as new.blade.php in projects folder of view file. new.blade.php
<form class="form-vertical" role="form" method="post" action="{{ route('projects.store') }}">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="control-label">Name</label>
<input type="text" name="name" class="form-control" id="name" value="{{ old('name') ?: '' }}">
#if ($errors->has('name'))
<span class="help-block">{{ $errors->first('name') }}</span>
#endif
</div>
<div class="form-group{{ $errors->has('notes') ? ' has-error' : '' }}">
<label for="notes" class="control-label">Notes</label>
<textarea name="notes" class="form-control" id="notes" rows="10" cols="10">
{{ old('notes') ?: '' }}
</textarea>
#if ($errors->has('notes'))
<span class="help-block">{{ $errors->first('notes') }}</span>
#endif
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Create</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
this form data save in ProjectController
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|min:3',
'notes' => 'required|min:10',
]);
$project = new Project;
$project->project_name = $request->input('name');
$project->project_notes = $request->input('notes');
$project->user_id = Auth::user()->id;
$duplicate = Project::where('project_name',$project->project_name)->first();
if($duplicate)
{
return redirect()->route('projects.index')->with('warning','Title already exists');
}
$project->save();
now I need after save this project data redirect page to users.blade.php file witch situated same projects folder with ulr project id. as example
localhost:8000/project/10/users
how can I do this? need some help......
edited
this is my redirect at projectcontrolle
return redirect()->route('projects.users',[$project]);
and routes
Route::get('/users', function(){
return view('projects.users');
})->name('projects.users');
You route looks like for url: localhost:8000/project/10/users
Route::get('project/{id}/users', function(){
return view('projects.users');
})->name('projects.users');
After save your project,
First you have to find the project id that you inserted.
$project->save();
$projectId = Project::all()->last()->id;
return redirect()->route('projects.users', ['id' => $projectId]);
for this localhost:8000/project/10/users url
try this kind of code
// For a route with the following URI: profile/{id}
return redirect()->route('profile', [$user]);
I need add comment box to My Laravel app. this is blade file for comment box in comments folder of view file
comments/form.blade.php
<form class="form-vertical" role="form" method="post" action="{{ route('projects.comments.create', $project->id) }}">
<div class="form-group{{ $errors->has('comments') ? ' has-error' : '' }}">
<textarea name="comments" class="form-control" style="width:80%;" id="comment" rows="5" cols="5"></textarea>
#if ($errors->has('comments'))
<span class="help-block">{{ $errors->first('comments') }}</span>
#endif
</div>
<div class="form-group">
<button type="submit" class="btn btn-info">Add Comment</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
</div>
and now I am going to include this file in to the show.blade.php file in tasks folder
tasks/show.blade.php
#include('comments.form')
this is My CommentController.php
public function postNewComment(Request $request, $id, Comment $comment)
{
$this->validate($request, [
'comments' => 'required|min:5',
]);
$comment->comments = $request->input('comments');
$comment->project_id = $id;
$comment->user_id = Auth::user()->id;
$comment->save();
return redirect()->back()->with('info', 'Comment posted successfully');
}
and comment model
public function user()
{
return $this->belongsTo(User::class);
}
but got following error
Undefined variable: project (View: C:\Users\Lilan\Desktop\ratakaju\resources\views\comments\form.blade.php)
how to fix this problem?
Admin login don't work and don't give me any error.
I have this routes in web.php file:
Auth::routes();
Route::prefix('admin')->group(function () {
Route::get('/login','Auth\AdminLoginController#showLoginForm')->name('admin.login');
Route::post('/login','Auth\AdminLoginController#login')->name('admin.login.submit');
Route::get('/','AdminController#getIndex')->name('admin.dashboard');
Route::get('/logout','Auth\AdminLoginController#logout')->name('admin.logout');
Route::post('/password/email','Auth\AdminForgotPasswordController#sendResetLinkEmail')->name('admin.password.email');
Route::get('/password/reset','Auth\AdminForgotPasswordController#showLinkRequestForm')->name('admin.password.request');
Route::post('/password/reset','Auth\AdminResetPasswordController#reset');
Route::get('/password/reset/{token}','Auth\AdminResetPasswordController#showResetForm')->name('admin.password.reset');
});
And this functions in controller(I only put here which have the problems)
public function showLoginForm()
{
return view('auth.adminlogin');
}
public function login(Request $request)
{
//validate the form data
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
//attempt to log the user in
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)){
//if successful, then redirect to their intended location
return redirect('/admin');
}
return redirect()->back()->withInput($request->only('email','remember'));
}
And in resources/views/auth/adminlogin.blade.php i have this code:
#extends('backend.public.includes.head')
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">ADMIN Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ route('admin.login.submit') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="{{ route('admin.password.request') }}">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
This was working days ago.. and now not, i'm looking all but don't find the error. In networking isn't showing anything and with a debug i don't see anything.
I try to reset password and when i reset it (i have a redirect in the function he redirect me good, only not working in normal login).
Errors aren't showed too
EDIT
Migrate file:
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->string('name',50)->unique();
$table->string('email',200)->unique();
$table->string('password');
$table->boolean('public')->default(true);
$table->rememberToken();
$table->timestamps();
});
}
Seed file:
private $arrayAdmins = array(
array(
'name' => 'Lluis',
'email' => 'lluis.puig#correo.biz',
'password' => 'correo1',
'public' => 1
)
);
public function run()
{
self::seedAdmins();
}
public function seedAdmins()
{
DB::table('admins')->delete();
foreach ($this->arrayAdmins as $admin)
{
$a = new Admin;
$a->name = $admin['name'];
$a->email = $admin['email'];
$a->password = $admin['password'];
$a->public = $admin['public'];
$a->save();
}
}
The admin login isn't working if i created with the seed. (So the problem i guess is with the "user created" with the seed.
I try to create one with php artisan tinker and it works.
SOLVED
I check the seed. The problem was de password isn't encrypted!
This line :
$a->password = $admin['password'];
Must be like this:
$a->password = bcrypt($admin['password']);
I'm currently trying to modify the laravel Auth two be able to register two different kinds of users, a seller and a buyer. Both have the same form, except one field, that only the seller has, called companyName.
So what I did is putting a dropdown for registration instead of the normal register button, this is what I got there:
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Registrieren
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li>
Als Käufer
Als Händler
</li>
</ul>
</div>
Then I made a route for this two kinds of registrations, like this:
Route::get('/register/{userType}', 'Auth\RegisterController#showRegistrationForm');
In the controller then I simply overwrote this showRegistrationForm function to pass the userType into my view, just like that:
public function showRegistrationForm($userType)
{
return view('auth.register', ['userType'=> $userType]);
}
And in my view, I got this:
#extends('master')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Registrieren
als <?php if ($userType == 'customer') echo "Käufer";if ($userType == 'seller') echo "Verkäufer";?></div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('sex') ? ' has-error' : '' }}">
<label for="sex" class="col-md-4 control-label">Anrede</label>
<div class="col-md-6">
<select class="form-control" id="sex">
<option value="male">Herr</option>
<option value="female">Frau</option>
</select>
</div>
#if ($errors->has('sex'))
<span class="help-block">
<strong>{{ $errors->first('sex') }}</strong>
</span>
#endif
</div>
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="firstName" class="col-md-4 control-label">Vorname</label>
<div class="col-md-6">
<input id="firstName" type="text" class="form-control" name="firstName"
value="{{ old('firstName') }}" required autofocus>
#if ($errors->has('firstName'))
<span class="help-block">
<strong>{{ $errors->first('firstName') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Nachname</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="name"
value="{{ old('name') }}" required autofocus>
#if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
#endif
</div>
</div>
<?php if ($userType == 'seller'){ ?>
<div class="form-group{{ $errors->has('companyName') ? ' has-error' : '' }}">
<label for="companyName" class="col-md-4 control-label">Firmenname</label>
<div class="col-md-6">
<input id="companyName" type="text" class="form-control" name="companyName"
value="{{ old('companyName') }}" required autofocus>
#if ($errors->has('companyName'))
<span class="help-block">
<strong>{{ $errors->first('companyName') }}</strong>
</span>
#endif
</div>
</div>
<?php } ?>
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Addresse</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email"
value="{{ old('email') }}" required>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Passwort</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password-confirm" class="col-md-4 control-label">Passwort
wiederholen</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control"
name="password_confirmation" required>
#if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
#endif
</div>
</div>
<div style="display:none;" class="form-group{{ $errors->has('role') ? ' has-error' : '' }}">
<label for="role" class="col-md-4 control-label">Deine Rolle:</label>
<div class="col-md-6">
<input name="role" type="radio"
<?php if ($userType == 'customer') echo "checked";?> value="Käufer"> Käufer<br/>
<input name="role" type="radio"
<?php if ($userType == 'seller') echo "checked";?> value="Verkäufer"> Verkäufer
#if ($errors->has('role'))
<span class="help-block">
<strong>{{ $errors->first('role') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Registrieren
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
So mostly basic, just few more fields then with the auth without modification and the companyName only showing up when accessed over the route /register/seller.
My RegisterController is of course also a bit modified, or especially the create function, it looks like this now:
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'firstName' => $data['firstName'],
'sex' => $data['sex'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);
if($data['role'] == 'Verkäufer'){
Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch($data['role']){
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
$user->companyName = $data['companyName'];
$user->save();
break;
default:
$user->attachRole(2);
break;
}
return $user;
}
And now comes the problem: As you can see, in my "invidual" views, which is basically just one anyway, I still post to the url /register, which I thought should work, but it doesn't.... Any ideas why this is not working? I also tried to add individual routes, so something like that:
Route::post('/register/seller', 'Auth\RegisterController#create');
Route::post('/register/buyer', 'Auth\RegisterController#create');
but thats not working as well. In both cases, I just get the same window back, as if there was an error (so my data still entered (expect the password), but nothing is registered or entered in the db, but as well there are no errors showing up, neither in my view, nor in the console.
What's interesting as well is the network tab, it seems like it definetely sends the request to /register as it shows up there with status code 302, but as well there's the route /register/customer again, and I'm wondering why...What's also interesting is that I think that somehow it kinda works, as if I enter a password with less then 6 characters or 2 different passwords, I get an error, so somehow the form seems to be posted, but nothing is entered into the db....
Any ideas why this happens like this and whats the problem?
First of all, I'd like to suggest you a Polymorphic approach to saving the users. Right now, you have only 2 user types, what if you get a third user type (say retailer or wholesaler or blah blah)... and for each of them, you will require different fields which may or may not fit in for all user types...
So, go with this
class User
{
public function profile()
{
return $this->morphTo();
}
}
class Seller
{
public function user()
{
return $this->morphOne('App\User', 'profile');
}
}
class Buyer
{
public function user()
{
return $this->morphOne('App\User', 'profile');
}
}
Now, In your routes, add these
Route::get('login', 'LoginController#show')->name('login.show');
Route::post('login', 'LoginController#login')->name('login.post');
Route::get('register', 'RegisterController#show')->name('register.show');
Route::post('register', 'RegisterController#register')->name('register.post');
Route::get('logout', 'LoginController#logout')->name('login.logout');
Now, in your form add a dropdown/radio button for User Type selection (you can also make seprate and run different routes and make these fields hidden);
Say,
<select name="type">
<option value="1">Buyer</option>
<option value="2">Seller</option>
<select>
Your RegisterController#register can be as follows:
use App\Buyer;
use App\Seller;
use Validator;
class RegisterController extends Controller
{
public function show()
{
return view('auth.register');
}
public function register()
{
$inputs = request()->all();
$validator = $this->validator($inputs);
if($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$userInputs = array_only($inputs, ['name', 'email', 'password']);
$userInputs['password'] = Hash::make($userInputs['password']);
switch($inputs['type'])
{
case 1:
$sellerInputs = array_only($inputs, ['company_name']);
$seller = Seller::create();
$user = $seller->user()->create($userInputs);
case 2:
$buyer = Buyer::create();
$user = $buyer->user()->create($userInputs);
default:
$user = null;
break;
}
if(!$user) {
return redirect()->back(); //Show flash messsage etc... and redirect back to show an error
}
auth()->attempt(array_only($inputs, ['email', 'password']));
return redirect(route('some.route'));
}
protected validator($inputs)
{
$rules = [
'name' => 'required|min:1|max:50',
'email' => 'required|email|min:1|max:100',
'password' => 'required|min:6|max:25',
// Other rules
];
$messages = [
// Any special messages if required...
];
return Validator::make($inputs, $rules, $messages);
}
}
Use same kind of coding structure in LoginController... I am simply going to write the login behind logging in below
public function login()
{
$inputs = request()->all();
//Validator etc...
if(auth()->attempt(array_only($inputs, ['email', 'password']))) {
return redirect(route('some.route'));
} else {
return redirect()->back(); // Again... Show some error flash message
}
}
Note :- I have not tested the code but I am 99% sure this should work... I wrote all this down myself... Took a damn half an hour almost!
Hope everything is answered and you understood. Let me know in the comments below if you have any other query :)
How can I customize the error messages (such as "These credentials do not match our records.") that are displayed upon unsuccessful login/registration without having to touch the foundation files? I'm looking for a solution and hopefully an elegant one, at least not touching AuthenticatesAndRegistersUsers nor ThrottlesLogins :)
I'm using the AuthController and forms provided by Laravel after executing:
php artisan make:auth
Controller:
(it only has a constructor and two methods, the rest falls on the foundation, the methods are:)
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
Form:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
{!! csrf_field() !!}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label class="col-md-4 control-label">E-Mail</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" value="{{ old('email') }}" required>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-sign-in"></i>Login
</button>
<a class="btn btn-link" href="{{ url('/password/reset') }}">Forgot Your Password?</a>
</div>
</div>
Thank you!
You can override getFailedLoginMessage on the AuthController which comes from the AuthenticatesUsers trait
protected function getFailedLoginMessage()
{
return 'what you want here.';
}
Or not override it and set a lang value for auth.failed. The getFailedLoginMessage method will check for Lang::has('auth.failed') and use that if its available.
For the actual validation error messages you can override the postLogin and pass your own array of messages to validate, or if you wanted to change them globally you can adjust them in the appropriate lang file in resources/lang/{lang}/validation.php.
You don't want to override the getFailedLoginMessage() method in AuthController. The proper solution is to change the message in the designed location. If you look in the Resources > lang > en folder, you will see an auth.php file. In it, there is a "failed" attribute with a message you can customize. Change it there. The orignial getFailedLoginMessage() method in the Laravel auth files in vendor looks to that location for a custom message first, before settling on the default.