Laravel Jetstream - How to join a default team at registration - php

I am trying to change Laravel Jetstream's logic in order to join a default team at registration rather than create a personal team. I found the method that does this:
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
])->validate();
return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
$user->currentTeam = Team::find(1); # SQLSTATE[42S22]: Column not found: 1054 Unknown column 'currentTeam' in 'field list'
$user->save();
});
});
}
The issue here is that currentTeam seems to be an created after the database level and not a column in the Database itself. The documentation says that currentTeam returns the Team model but doesn't say how to update the current users team programmatically.
I can see I can manually use a DB query to insert a row into the team_user table but there must be a method to do this.
return DB::transaction(function () use ($input) {
return tap(User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]), function (User $user) {
DB::table('team_user')->insert(['user_id' => $user->id, 'team_id' => 1, 'role' => 'rfn']);
$user->current_team_id = 1;
});
});
Any help would be appreciated, I understand this will be reliant on this team always existing in the Database but further measures will be implemented so it cannot be removed.

After some tinkering with a local Laravel version, this is was I came up with. This assumes the team you wanna add the user to is already created somehow, possibly through a seeder, or created manually. The file you need to edit is app/Actions/Fortify/CreateNewUser.php, namely the createTeam method.
Instead of creating a new team, we want to grab a team from the database, attach it to the newly registered user and then make that now attached team the users current team.
protected function createTeam(User $user)
{
$team = Team::first();
$user->teams()->attach($team);
$user->switchTeam($team);
}
The reason we first need to attach the team first is that switchTeam checks if a user belongs to that team if it doesn't it returns false and doesn't switch to the new team. By attaching the team first we make the user belong to that team before we can actually switch to it as the current team.

you can assign role as well in above answer of #KimHallberg as below
$team = Team::first();
$user->teams()->attach($team, array('role' => 'editor'));
$user->switchTeam($team);

Related

Laravel 5.5 unique validation rule on seperate table with different column name

So I have users and companies. A user belongs to one company.
I want to validate a user registration so that the business_name field they use to register is unique in the companies table, the goal is to not allow users from creating duplicate companies.
Here is my register function:
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'business_name' => 'required|unique:companies',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6',
]);
if ($validator->fails()) {
return response()->json(['error'=>$validator->messages()], 401);
}
}
The field I want to compare against is the companies.name to check for uniqueness.
Is this possible? At the moment it is trying to look for business_name in the companies table.
Never mind, managed to figure it out. Just needed an extra parameter to specify the column name:
'business_name' => 'required|unique:companies,name',

Laravel addOrUpdate() on basis of related table values?

Below is something I am trying to do:
I have users table and user_profiles table and I am inserting name, email in users table and phone, address, .... etc in user_profiles table.
I have to match each value to prevent duplication of user, I have found this laravel method addOrUpdate() but it works only for one table. But I have to match user_profiles values too i.e phone,address.
Below is example code
$result = $customer->updateOrCreate([
'name' => $request->name,
'city_id' => $request->city_id,
'area_id' => $request->area_id,
'email' => $request->email
], [
'name' => $request->name,
'city_id' => $request->city_id,
'area_id' => $request->area_id,
'email' => $request->email
]);
There any way to achieve this using Laravel techniques?
Regards
First make a relationship with user and user_profiles model like-
public function userProfile()
{
return $this->hasOne('App\Model\UserProfile','user_id','id');
}
And then in your post controller as you want to match each value to prevent duplication of user-
$result = User::where('name',$request->name)->where('email',$request->email)
->whereHas('userProfile', function($q) use ($request){
$q->where('city_id'$request->city_id)->where('area_id',$request->area_id)
)->first();
if(!$result){
////your registration here
}
If you want to check if a user with exactly the same data exists, you can't use updateOrCreate(). Do this instead:
$user = User::where('name', $request->name)->where('email', $request->email)->first();
$profile = $user->profile()->where('phone', $request->phone)->where('address', $request->address)->count();
if ($user && $profile) {
// User exists.
}
I would recommend using Laravel's Validator Facade. https://laravel.com/docs/5.4/validation#manually-creating-validators
This would check to make sure the name and email fields of the users and users_profile table are unique.
$validator = Validator::make($request->all(), [
'name' => 'required|unique:users|unique:users_profile',
'email' => 'required|unique:users|unique:users_profile',
]);
You could use updateOrCreate for both of your models for sake of uniqueness i assume email should be unique so first updateOrCreate() method will check if user exists for parameter $request->email then update if not then create and return user model instance (in both update/create case)
Second updateOrCreate() on UserProfile will check if there exist any data for user_id then update else add new row, I assume user_id will be a foreign key in user profile table
$user = User::updateOrCreate([
'email' => $request->email
], [
'name' => $request->name,
'email' => $request->email
]);
UserProfile::updateOrCreate([
'user_id' => $user->id
], [
'user_id' => $user->id,
'city_id' => $request->city_id,
'area_id' => $request->area_id
]);

Laravel custom validation on registration form

I'm currently struggling with a bit of validation on a registration form.
Basically when a user registers it will check if the unique code they have entered is valid and if not doesn't let them sign up.
But in my codes table which this reads from I also have an expiry date on the code.
I need to do another check after it is deemed valid that the expiry date hasn't passed, in other words it is not greater than now.
I think you can do this in the validator but I'm struggling a bit with the syntax and not sure where it should go. Here is my code:
protected function validator(array $data)
{
return Validator::make($data, [
'code' => 'required|exists:codes',
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'date_of_birth' => 'required|date',
'password' => 'required|min:6|confirmed',
'accept_terms' => 'required|accepted',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
Code::where('code', $data['code'])->increment('uses');
$data['code_id'] = Code::where('code', $data['code'])->value('id');
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'date_of_birth' => $data['date_of_birth'],
'accept_terms' => $data['accept_terms'],
'code' => $data['code'],
'code_id' => $data['code_id'],
'password' => bcrypt($data['password']),
]);
}
Thanks in advance :)
As long as you're using Laravel v5.3.18 (or higher) you can use the Rule Class to save you having to define a custom rule.
This:
'code' => 'required|exists:codes',
Can be replaced with:
'code' => [
'required',
Rule::exists('codes')->where(function ($query) {
$query->where('expiry_date', '>=', Carbon::now());
}),
],
(the above is assuming expiry_date is the actual name of the column in your db table).
Documentation: https://laravel.com/docs/5.3/validation#rule-exists
Just make sure you import those facades.
Hope this helps!
You can create custom validation rule. Create service provider and register it. Then add something like this:
Validator::extend('is_code_valid', function($attribute, $value, $parameters, $validator) {
$code = Code::where('code', $value)->where('date', '>', Carbon::now())->first();
return !$code->isEmpty(); // Pass if valid code exists in DB.
});
And then use it:
'code' => 'required|is_code_valid',

Laravel create multiple user tables

I have two tables - users and user_attributes.
During registration user I would like to not only enter the user in the user table but also create his attributes.
AuthController
protected function create(array $data)
{
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
return UserAttribute::create([
'user_id' => $data['id'], // Undefined index: id
'lvl' => 0,
'exp' => 0,
'currency' => 500,
'premium_currency' => 5,
]);
}
How do I get user_id?
PS: I'm sorry for my english.
Do this
$user =new User;
$user->thing1 = 12;
$user->thing2 =32;
$user->save();
And now as soon as you have called the save method you can get the id by doing
$user->id;
Remember! It will only work after you have called the save method.
Also remember to replace my data with your data.
For further info and explanation see here: https://laravel.com/docs/5.2/eloquent#basic-inserts
Best of luck!

How to perform validation when updating a unique field using Http\Request in Laravel

I have a customers table that I use a CustomerRequest to validate the fields, through the use of the rules function. The table has an email field which is required and is unique. This works fine when I create the customer, however when I update the customer info (let's say I got their last name spelled wrong) my request fails because the email address is already in the database.
Here is my CustomerRequest:
public function rules()
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email',
];
}
I would like to reuse the CustomerRequest for all of the customer vaildation, how can I go about doing this?
You need to check here for request type as well as customer id for update and then return rules according to request. Something like this
public function rules(Request $customer_request)
{
return [
'givenname' => 'required',
'surname' => 'required',
'email' => 'required|unique:customers,email,'.$customer_request->get('customer_id'),
];
}

Categories