I am trying to get into Laravel 4 and am having a problem with editing users I have created. So far I have controllers, views, and routes to show a user and then edit the user by clicking the "Edit" button but when I click the submit button I keep getting a NotFoundHttpException and the "Crash/Error" orange and white Laravel screen. I did, however, notice that the URL changes from showing the username (ex - public/users/av1/edit - with av1 being the username) to only saying {username} (ex -public/users/{username}/edit). I am still new to Laravel but my thought is that I'm not passing the username along properly but I know that it could also be the Controller or route as well. I have tried removing and changing sections of code and have found that if I remove the code from the Controller I still get a URL with {username} but I at least don't get the "Crash/Errors" screen. If anyone could help explain where I am going wrong it would be very much appreciated!
Here is my view:
#extends('layout.main')
#section('content')
{{ Form::model($user, array('route'=>'user-edit-post')) }}
<div>
{{ Form::label('username', 'Username:')}}
{{ Form::text('username') }}
#if($errors->has('username'))
{{ $errors->first('username') }}
#endif
</div>
<div>
{{ Form::label('password', 'Password:')}}
{{ Form::password('password') }}
#if($errors->has('password'))
{{ $errors->first('password') }}
#endif
</div>
<div>
{{ Form::label('password_confirmation', 'Confirm Password:')}}
{{ Form::password('password_confirmation') }}
#if($errors->has('password_confirmation'))
{{ $errors->first('password_confirmation') }}
#endif
</div>
<div>
{{ Form::submit('Edit User') }}
</div>
#stop
My User Controller functions that relates to editing:
public function getEdit($username){
$user = User::where('username', '=', $username);
if($user->count()) {
$user = $user->first();
return View::make('users.edit')
->with('user', $user);
} else {
return App::abort(404);
}
}
public function postEdit($username){
$validator = Validator::make(Input::all(),
array(
'first_name' => 'required|max:20',
'last_name' => 'required|max:20',
'email' => 'required|max:50|email',
'username' => 'required|max:20|min:3',
'password' => 'required|min:6',
'password_confirmation' => 'required|same:password'
)
);
if($validator->fails()){
return Redirect::route('user-edit')
->withErrors($validator);
} else {
/*Edit User*/
$user = User::whereUsername($username)->first();
$password = Input::get('password');
$user->password = Hash::make($password);
$user->first_name = Input::get('first_name');
$user->last_name = Input::get('last_name');
$user->email = Input::get('email');
$user->username = Input::get('username');
/*password is the field $password is the variable that will be used in the password field*/
if($user->save()){
return Redirect::route('home')
->with('global', 'The password has been changed.');
}
return Redirect::route('home')
->with('global', 'The password could not be changed.');
}
}
And lastly my Routes:
/*Edit users (GET)*/
Route::get('users/{username}/edit', array(
'as' => 'user-edit',
'uses' => 'UserController#getEdit'
));
/*Edit Order (POST)*/
Route::post('/orders/{orders}/edit', array(
'as' => 'order-edit-post',
'uses' => 'OrderController#postEdit'
));
Change
{{ Form::model($user, array('route'=>'user-edit-post')) }}
To
{{ Form::model($user, array('route'=>array('user-edit-post', $user->username))) }}
Your route need additional parameters, so you need supply your parameters with your route name when binding model to form.
Yep, after reading the comment. I found the reason of your trouble here is the redirect in the postEdit function:
Change:
if($validator->fails()){
return Redirect::route('user-edit')
->withErrors($validator);
}
Into
if($validator->fails()){
return Redirect::route('user-edit', $username)
->withErrors($validator);
}
Again, your route need parameters. When the validation fails, you have been redirected to a wrong URL.
Related
I am using Laravel 5.2 and trying to make a password change form with its controller. I have added the following routes:
Route::get('changepassword', array('as' => 'reset.password', 'uses' => 'PasswordController#edit'));
Route::post('resetpasswordcomplete', array('as' => 'reset.password.complete', 'uses' => 'PasswordController#update'));
The Http\Controllers\Auth\PasswordController has the following methods:
public function edit() {
return View::make('auth/passwords/change');
}
public function update() {
$hasher = Sentinel::getHasher();
$oldPassword = Input::get('old_password');
$password = Input::get('password');
$passwordConf = Input::get('password_confirmation');
$user = Sentinel::getUser();
if (!$hasher->check($oldPassword, $user->password) || $password != $passwordConf) {
Session::flash('error', 'Check input is correct.');
return View::make('auth/passwords/change');
}
Sentinel::update($user, array('password' => $password));
return Redirect::to('/');
}
The view is as such:
#if (Session::get('error'))
<div class="alert alert-error">
{{ Session::get('error') }}
</div>
#endif
{{ Form::open(array('route' => array('reset.password.complete'))) }}
{{ Form::password('old_password', array('placeholder'=>'current password', 'required'=>'required')) }}
{{ Form::password('password', array('placeholder'=>'new password', 'required'=>'required')) }}
{{ Form::password('password_confirmation', array('placeholder'=>'new password confirmation', 'required'=>'required')) }}
{{ Form::submit('Reset Password', array('class' => 'btn')) }}
{{ Form::close() }}
I get the ReflectionException error because I think the PasswordController is inside of the Auth folder and thus is only accessible to guests who want to reset their forgotten password using the auth scaffold. I would like to know how I could allow a logged in user to access this controller so that they could change their passwords if they wished?
EDIT: I tried doing the following after Alexy's solution:
public function __construct()
{
$this->middleware('guest', ['except' => ['resetpasswordcomplete', 'changepassword']]);
}
It still brings me back to home page.
Change controller path in routes.php to:
Route::get('changepassword', array('as' => 'reset.password', 'uses' => 'Auth\PasswordController#edit'));
Route::post('resetpasswordcomplete', array('as' => 'reset.password.complete', 'uses' => 'Auth\PasswordController#update'));
I have an issue with my the update method in my controller.
Normally everything works and it takes care of itself, but this time its not working.
My controller:
public function update($id)
{
$input = Input::all();
$validation = Validator::make($input, Vehicle::$rules, Vehicle::$messages);
if ($validation->passes())
{
$this->vehicle->update($id, $input);
return Redirect::route('admin.vehicles.index')->with('success', 'Car Updated');
}
return Redirect::back()
->withInput()
->withErrors($validation);
}
Repository:
public function update($id, $input)
{
print_r($id);
die();
}
This prints out:
{vehicle}
from the URI:
http://localhost/admin/vehicles/1/edit
My form:
{{ Form::open(['route' => 'admin.vehicles.update', 'class' => 'form-horizontal edit-vehicle-form', 'method' => 'PATCH']) }}
// inputs
<div class="form-group">
{{ Form::submit('Update Vehicle', ['class' => 'btn btn-success']) }}
</div>
{{ Form::close() }}
Route:
Route::resource('/admin/vehicles', 'VehiclesController');
Where is this going wrong? How can I get this form to send the ID not the word vehicle?
I am having an issue with my resource route when calling the update method.
I get this error:
Creating default object from empty value
The controller:
public function update($id)
{
$input = Input::all();
$validation = Validator::make($input, Vehicle::$rules, Vehicle::$messages);
if ($validation->passes())
{
$this->vehicle->update($id, $input);
return Redirect::route('admin.vehicles.index')->with('success', 'Car Updated');
}
return Redirect::back()
->withInput()
->withErrors($validation);
}
repository:
public function update($id, $input)
{
$vehicle = Vehicle::find($id);
$vehicle->VRM = $input['VRM'];
$vehicle->make = $input['make'];
$vehicle->model = $input['model'];
$vehicle->description = $input['description'];
$vehicle->save();
}
Route:
Route::resource('/admin/vehicles', 'VehiclesController');
If I print the ID then it shows {vehicle}.
My form is this:
{{ Form::open(['route' => 'admin.vehicles.update', 'class' => 'form-horizontal edit-vehicle-form', 'method' => 'PATCH']) }}
// input fields etc
{{ Form::close() }}
I think there is something wrong with the form possibly? Since when the error is thrown the URL is:
http://localhost/admin/vehicles/%7Bvehicles%7D
Never had any issues before with using resource routes with CRUD applications and cant see where this is going wrong?
You need the id in update route...
{{ Form::open(['route' => array('admin.vehicles.update', $vehicle->id), 'class' => 'form-horizontal edit-vehicle-form', 'method' => 'PATCH']) }}
Im trying to make a login in laravel and it wont give me a succes login.
This is the code for my login:
public function login()
{
$user = array(
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password'))
);
if (Auth::attempt($user)) {
return Redirect::to('showlogin');
}
else{
return 'Wrong username/password';
}
}
public function showlogin()
{
return View::make('login');
}
It always gives me the message: "wrong username/password". It doesn't matter what I put in. When I put the right combination it gives me the message and when I give type in a wrong combination it gives me message as well.
Routes:
Route::get('admin', 'TestController#login');
Route::get('login', 'TestController#showlogin');
and the 2 views
Login:
#extends('layout')
#section('content')
<h1>Login</h1>
{{ Form::open(array('url' => 'admin', 'method' => 'get')) }}
<div>
{{ Form::label('email', 'E-mail:') }}
{{ Form::text('email') }}
{{ $errors->first('email') }}
</div>
<div>
{{ Form::label('password', 'Password:')}}
{{ Form::password('password')}}
{{ $errors->first('password') }}
</div>
<div>
{{ Form::submit('Login')}}
</div>
{{ Form::close()}}
#stop
Admin:
#extends('layout')
#section('content')
<h1>Admin page</h1>
#stop
What is going wrong here?
You don't need to hash the password when passing it to attempt(). Internally the method will use Hash::check which needs the plain password to compare check if it's correct. (Every hash created will be new because it's composed of a random salt)
Without hashing it should work:
$user = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
$user = array(
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password'))
);
In this part of the code, you need to change the key "email" to "username". As far as I know, the Laravel User authentication checks on username + password.
Also: hashing is when saving a pass in the database. You won't need to create a Hash here. The attempt-function does that for you.
I have a weird problem with my Laravel-4 Authentication. Only my first database line can login in my Laravel project, the others return false.
I use Authentication a bit different than expected. I don't have a username, only a password, which is also called 'code'. I also tried this with a username (as "party"), but that also doesn't seem to work.
I added a table "password_unh" (= password unhashed) to my database, of course this is not how it's supposed to be in the end, but it's to check my password (since my password table is hashed), and I also see this as my 'party'.
Here is my code (I put the code about 'party' in comment)
login.blade.php
#extends("layout")
#section("content")
{{ Form::open([
"route" => "party/login",
"autocomplete" => "off"
]) }}
<!--{{ Form::label("party", "Party") }}
{{ Form::text("party", Input::get("party"), [
"placeholder" => "Christmas party Smith"
]) }}-->
{{ Form::label("code", "Code") }}
{{ Form::password("code") }}
#if($errors->has())
#foreach ($errors->all() as $error)
<div class='error'>{{ $error }}</div>
#endforeach
#endif
{{ Form::submit("login") }}
{{ Form::close() }}
#stop
#section("footer")
#parent
<script src="//polyfill.io"></script>
#stop
UserController.php
<?php
use Illuminate\Support\MessageBag;
class UserController extends Controller
{
public function loginAction() {
$errors = new MessageBag();
if ($old = Input::old("errors"))
{
$errors = $old;
}
$data = [
"errors" => $errors
];
if (Input::server("REQUEST_METHOD") == "POST")
{
$validator = Validator::make(Input::all(), [
//"party" => "required",
"code" => "required"
]);
if ($validator->passes())
{
$credentials = [
//"password_unh" => Input::get("party"),
"password" => Input::get("code")
];
if (Auth::attempt($credentials))
{
return Redirect::to('profile');
}
}
$data["errors"] = new MessageBag([
"code" => [
"Party and/or code invalid."
]
]);
//$data["party"] = Input::get("party");
return Redirect::route("party/login")
->withInput($data);
}
return View::make("party/login", $data);
}
}
database users table
Actualy, you should have at least username and password field in $credentials array.
I can see you miss that in database table as well.
This is not ideal but you could do
$user = User::where('password',Hash::make(Input::get('code')));
if(Auth::loginUsingId($user->id))
{
//do blah
}
or
if(Auth::login($user))
{
//do blah
}