I'm using Laravel 5.5 and I want newly registered users to activate their account by confirming their email address. Also, I need some extra fields or name alterations on the existent Laravel User model. name is replaced by first_name and last_name.
I found out that Laravel manages most parts of the registration in the Auth/RegisterController and so I modified what I needed:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:12',
'first_name' => 'required|string|min:2',
'last_name' => 'required|string|min:2',
'terms' => 'accepted'
]);
}
The validator works fine, if I change the first_name min:n, it is correctly thereafter validated and shown to the user [the validation errors].
protected function create(array $data)
{
$user = User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'status' => 'inactive',
'password' => bcrypt($data['password']),
'api_token' => static::generateApiKey(),
]);
$activationLink = route('account.activation', static::generateRandomString());
Mail::to($user)->send(new UserAccountConfirmationMail($user, $data['password'], $activationLink));
return $user;
}
However, the creation (create(array $data)) does not work at all. I kind of feel like the code is not even executed (tried to add dd or Log::info('...') in order to find out whether or not it at all is executed) and nothing truly happens when I attempt to register. The page is sort of refreshed, however, no message on the user creation (if successful or not, ...), and subsequently no email in my box.
Am I missing out on some crucial detail here?
One of these days that you have spent hours on finding the errors has just finished. The validator, of which I thought was all fine because it was ordinarily displaying the errors, has been the turning point. I forgot to remove name from the validation. However, this validation error was never shown to me since I only caught these errors on display that I truly needed.
Solution:
return Validator::make($data, [
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:12',
'first_name' => 'required|string|min:2',
'last_name' => 'required|string|min:2',
'terms' => 'accepted'
]);
Related
I've got a User model that hasOne Membership model, with a users table and a memberships table (each entry in the memberships table has a foreign key linked to a user_id).
I've made a registration page that lets the user have a 7 days trial period on the membership but I'm having trouble storing the data.
This is the dd() of the data in the registration form:
"_token" => "ckRlMligEyTwu7ssOi4TmesycbsPpVQlrJ4jQaBd"
"username" => "JaneDoe"
"password" => "password"
"password_confirmation" => "password"
"expiration" => "2021-04-30"
Now in my controller I've got the following store() method:
public function store(Request $request) {
// validating
$this->validate($request, [
'username' => ['required', 'max:200'],
'password' => 'required|confirmed',
'expiration' => 'required'
]);
// storing
User::create([
'username' => $request->username,
'password' => Hash::make($request->password),
'expiration' => $request->expiration
]);
}
This won't store anything in the memberships table and I have no idea how to correctly write the store method using the Model's Eloquent Relationships declared.
Thanks for the help.
EDIT:
While trying to make some sense i've modified the store() function, now looks like this:
public function store(Request $request) {
// validating
$this->validate($request, [
'username' => ['required', 'max:200'],
'password' => 'required|confirmed',
'expiration' => 'required'
]);
// storing
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership(Membership::create([
'expiration' => $request->expiration
]));
}
Now seems like Laravel doesn't know where to get the user_id of the newly created user, like the error suggests:
SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into `memberships` (`expiration`, `updated_at`, `created_at`)
Your solution is to do:
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership()->create([
'expiration' => $request->expiration
]);
Using the relation (membership() not membership as an attribute) will already know the relation key (user_id in this case).
You can see more info about this in the documentation.
Other way of doing same is:
$membership = new Membership([
'expiration' => $request->expiration
]);
User::create([
'username' => $request->username,
'password' => Hash::make($request->password)
])->membership()->save($membership);
More info about save() on the documentation.
I want to create a function and say in register form, user can put just Gmail or Ymail
And if the email isn't from them, shows: "Please put a valid email"
Register controller:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'username' => 'required|string|alpha_dash|max:25|unique:users',
]);
}
To put some customized message, you need to paste third arguments to Validator::make
See this documentation link
And in the email validation rules, you need to add regex rule
like this
regex:/gmail|ymail]/
Regex Documentation
$message = ['email.regex' => 'Please put a valid email'];
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users|regex:/gmail|ymail]/',
'password' => 'required|string|min:6|confirmed',
'username' => 'required|string|alpha_dash|max:25|unique:users',
], $message);
when a user tries to register I require them to enter an organization ID, I want that organization ID to be checked against my Organization table and see if it exists. If it exists then register the user and if it fails then return an error message. I've been looking around online and couldn't personally find anything like this. If anybody could help, I'd greatly appreciate it.
I am using Laravel 5.6 with the default auth.
Validator:
return Validator::make($data, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'org_id' => 'required|string|max:16',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
User Create:
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'org_id' => $data['org_id'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'is_active' => 1
]);
You're looking for the exists rule of Laravel's Validation:
'org_id' => 'required|string|max:16|exists:organizations,id',
The rule is essentially
exists:{table},{column?}
Where table is required, and column is optional, generally used if the name (in this case org_id) is different from the column you want to compare.
For full details, check the Documentation.
In my RegisterController in Laravel I'm having trouble returning the errors to my front-end. Our application is built as a REST API, so the registration of a new user happens through an AJAX post to the registration route. This works fine if the validation passes, but if the validation fails, no errors are shown. It just redirects to a Laravel homepage. We are not using Blade for the front-end, so it's not possible to get the default validation errors from Blade. The front-end is a ReactJS client that communicates with the back-end through AJAX calls.
How do I get a JSON with the fields that didn't pass validation back to my front-end?
protected function validator(array $data)
{
return Validator::make($data, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'birth_year' => 'required|integer|min:4',
'lat' => 'required|numeric',
'lon' => 'required|numeric',
]);
}
you can solve it by return the errors as json respone
$validator = Validator::make($data, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'birth_year' => 'required|integer|min:4',
'lat' => 'required|numeric',
'lon' => 'required|numeric',
]);
if ($validator->fails()) {
return response()->json($validator->messages(), 200);
}
Your code is fine, you can catch the errors because laravel will automatically return a JSON response with a 422 HTTP status.
So basically in your ajax use the error function, if the validator fails ajax will automatically execute the code you have in your error from ajax.
For more info on how to properly handle error's for your ajax please take a look at this question. Displaying validation errors in Laravel 5 with React.js and AJAX
I solved the problem by disabling the 'guest' middleware in the RegisterController. I'm not sure if this is a solid solution, but for now it works.
My application uses the standard validator, and my form makes the user provide an email address. They may continue as a guest, but if they do want to create an account; the only thing they will have to provide is a password and in combination with that email address will create the user account.
However, my issue is I am not sure how to use the validator exists only if the password field has been filled in.
$this->validate($request, [
'first_name' => 'required',
'email' => 'required|confirmed|email',
'last_name' => 'required',
'street_1' => 'required',
'zip_code' => 'required',
'phone_1' => 'required',
'password' => 'required_if:account,1|confirmed',
]);
I could do a check and return redirect with an error message, but I'd prefer to go through the validator if I can.
The simplest solution is to put your validation rules into an array then perform your desired check. So if the user checked the "account creation" checkbox, add the rules.
$rules = [
'first_name' => 'required',
'last_name' => 'required',
'street_1' => 'required',
'zip_code' => 'required',
'phone_1' => 'required',
'password' => 'required_if:account,1|confirmed',
]
if ($request->input('acount') == 1) {
$rules['email'] = 'required|confirmed|email'
}