Laravel 8 - Multi Auth with two diffirent registration form? - php

I'm using laravel breeze as auth scaffolding package I want to know How can I
create two diffirent registration form for two User Types here is a simple explanation of hwat I want to achieve:
resources/auth/developer :
developer-register.blade.php
resources/auth/designer :
designer-register.blade.php
if the Visitor choose to register as "developer" it will display a diffirent form. and same thing for if the Visitor choose to register as "designer" it will display a diffirent form with fields.
I wish you understand what I want to achieve with this easy explanation.

Ok, so i've not used laravel/breeze myself (yet) but it shouldn't be much different from doing it in standard Laravel!
Views
By default, it looks like the breeze scaffolding is going to hit a create() method on the RegisteredUserController which will return a single view like so:
RegisteredUserController.php
/**
* Display the registration view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.register');
}
You have a few options here:
Replace this view with another
Add some logic to change the view which is returned based on the request being made (you can inject a Request object into the route like any other)
public function create(Request $request)
{
if ($request->has('developer')) {
return view('auth.developer-register');
} else {
return view('auth.designer-register');
}
}
Keep the original auth.register view and handle the logic in the blade template.
Registration
The forms on each of your registration pages will have an action that points to a controller route. This will likely be the RegisteredUserController within which you will find a store() method that handles the creation of a User model.
RegisteredUserController.php
/**
* Handle an incoming registration request.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*
* #throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|confirmed|min:8',
]);
Auth::login($user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]));
event(new Registered($user));
return redirect(RouteServiceProvider::HOME);
}
As you can see, this store() method is handling the creation of a User model and then authenticating it before redirecting the user to the home route.
What you could do, is check the request for the the requested user type and then use a switch statement to change the type of use being created.
switch ($request->get('user_type'))
case 'developer':
$user = Developer::create([ /* add details here */ ]);
break;
case 'designer':
$user = Designer::create([ /* add details here */ ]);
break;
Auth::login($user);
I hope this will at least inspire you with your own solution!

Related

Delete dynamic form data from database laravel

EducationalDetailsController.php
public function update(EducationalDetailsRequest $request)
{
$educationDetails = $request->validated();
foreach ($educationDetails['educational_details'] as $education) {
$educationDetail = $this->educationalDetailsManager->find($education['education_id']);
$educationDetail->update(['education_level' => $education['education_level'],
'passed_year' => $education['passed_year'], 'institution' => $education['institution']]);
}
}
EducationalDetailManager.php
public function find(int $education_id){
return $this->educationalDetails->find($education_id);
}
EducationalDetailRequest
<?php
namespace App\Talent\EducationalDetails\Requests;
use Illuminate\Foundation\Http\FormRequest;
class EducationalDetailsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array<string, mixed>
*/
public function rules()
{
return [
'employee_id'=>'required|exists:employees,id',
'educational_details' => ['required', 'array'],
'educational_details.*.education_id'=>'required',
'educational_details.*.education_level' => 'required|string',
'educational_details.*.passed_year' => 'required|date_format:Y|before_or_equal:' . now()->format('Y'),
'educational_details.*.institution' => 'required|string',
];
}
}
EducationDetails.php
<?php
namespace App\Talent\EducationalDetails\Models;
use App\Talent\Employee\Model\Employee;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class EducationalDetails extends Model
{
use HasFactory;
protected $fillable = [
'employee_id',
'education_level',
'passed_year',
'institution'
];
public function employee(){
return $this->belongsTo(Employee::class);
}
}
This is my get API data for the edit form,
Here I am trying to create an update API of the educational details form which is dynamic.
Here update code is working fine that is whenever I edit form contents and hit save and continue the data present in the database gets updated only when those data are present in the table. But I also want to add new data when new data is added into the form and delete data whenever the user clicks the remove button in the form and hits save and continue. I am pretty new to laravel and I have no idea how can I implement that any help or suggestion will be really appreciated.
With possible future developments, the thing you try to have to do will evolve into something too complex. If I understood correctly, you are using a frontend framework like Vue, React, etc. In this situation, the best option is to use multiple save buttons for each education entry.
When someone clicks the save button, you will check the related education entry for having an id attribute on the frontend side. If it already has an id attribute, you can make an HTTP request to the update endpoint. Otherwise, you will make an HTTP request to the create endpoint, grab the id attribute from the response, and assign it to the education entry on the frontend side.

JWT Authentication / Laravel

Im new at Laravel, i made a login page for my backend application(its working fine) and then i did the JWT documentation to install and begin to use(https://jwt-auth.readthedocs.io/en/develop/).
In my Controllers i used after:
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
Now everytime i try to enter my same login i cant.
How can i enter my login now with JWT?
If you're using Laravel 8, the newly recommended route is to use Laravel's Sanctum feature:
https://laravel.com/docs/8.x/sanctum
For this, if you want stateful logins, you simply post to any controller that then makes an Auth::attempt call like this:
class AuthController extends Controller
{
/**
* Store a newly created resource in storage.
*
* #param Request $request
* #throws ValidationException
*/
public function store(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials, true)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
}
}
I recently set up my login system successfully on React using this package:
https://github.com/koole/react-sanctum
For Stateless, you can follow the documentation here:
https://laravel.com/docs/8.x/sanctum#api-token-authentication

Verification before creating a user in RegistrationController

In this Laravel script, when a user puts his details for registration, Laravel first creates the user, then sends an email for verification, I, on the contrary, want this action:
I want after the user puts his details, Laravel sends the email verification and if the verification is successful, creates the user.
The RegistrationController:
<?php
namespace App\Http\Controllers\Auth;
use App\GeneralSetting;
use App\Service;
use App\ServicePrice;
use App\User;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default, this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = 'user/dashboard';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
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',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
$general = GeneralSetting::first();
$code = str_random(6);
if($general->email_verification == 1){
$ev = 0;
send_email($data['email'], $data['name'], 'Verification'
,'Your code is'.':' . $code);
}else {
$ev = 1;
}
$api = str_random(30);
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'verification_time' => Carbon::now(),
'verification_code' => $code,
'email_verify' => $ev,
'api_key' => $api,
]);
$services = Service::all();
foreach ($services as $service){
$servicePrice = new ServicePrice();
$servicePrice->category_id = $service->category_id;
$servicePrice->service_id = $service->id;
$servicePrice->user_id = $user->id;
$servicePrice->price = $service->price_per_k;
$servicePrice->save();
}
return $user;
}
}
When user sign up, the information which He provide is store in the users Table at least you set the $table property of the model to something else. And the fact of saving users informations in the tables is part of the user registration process. It seams weird the fact that you want to register the user only after he verify his email address. My advice It will be to not log the user after he signed up and redirect him to another page even if he try to login you will set the loggin condition to log only user who has his email address verified.
You should implement a feature similar to how password reset works.
You can leave your create method as is. There is also a register() function inside your RegisterController.
1. In that function you should override the part where the user gets logged in and instead you should redirect him to a page with a message saying that an email has been send and he needs to verify it.
Now as i see you send a code with the email.
2. You should also provide a link inside the email that redirects the user to a code submission page.
3. If you dont have a page like that you should create one. A blade file, a function to view it and a route on your web.php file to access it.
4. Inside that page you will have a <form> with one <input> field e.g. 'code' where its action will point to a function you will create e.g. validateCode() inside your RegisterController.
Then this functions job will be to check on the Users table for a user with a code same with the one provided from the request, if such a user exists then it will update the 'email_verify' field to 1 loggin in the user and redirect him to the panel, if not the it will redirect back to code submit view:
public function validateCode(Request $request)
{
$user = User::whereVerificationCode($request->get('code'))->first();
if($user){
$user->verify_email = true;
$user->update();
Auth::login($user);
return redirect()->route('home');
}else{
return redirect()->back();
}
}
Also it would be good if you change the code your are generating to a 9 or 10 digit one or even better to a hashed string for security reasons.

Laravel 5.1 - Custom validation language file

Is it possible to conditionally set a custom language file (e.g. resources/lang/en/validation_ajax.php) for a validation request? Just to be clear, I don't want to change the app language, just use another set of messages depending on the request origin.
When I make an ajax validation call I want to use different messages since I'm showing the error messages below the field itself. So there's no need to show the field name (label) again.
I know you can define labels on 'attributes' => [] but it's not worth the effort since I have so many fields in several languages.
I'm using a FormRequest (there's no manual call on the Controller just a type hint).
You can override the messages() method for a specific request (let's say login request). Let me show you: At first place, you need yo create a new custom Form Request, here we will define a custom message for email.required rule:
<?php namespace App\MyPackage\Requests;
use App\Http\Requests\Request;
class LoginRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
public function messages()
{
return [
'email.required' => 'how about the email?',
];
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'email' => ['required', 'email'],
'password' => ['required', 'confirmed']
];
}
}
Only email.required rule message will be override. For password it will display the default message set at validation.php file.
Now, apply the form request at your controller function like a type hint:
class LoginController{
public function validateCredentials(LoginRequest $request){
// do tasks here if rules were success
}
}
And that is all. The messages() method is useful if you need are creating custom packages and you want to add/edit validation messages.
Update
If you need to carry the bag of messages on into your package's lang file then you can make the following changes:
At your package create your custom lang file:
MyPackage/resources/lang/en/validation.php
Add the messages keeping the same array's structure as project/resources/lang/en/validation.php file:
<?php
return [
'email' => [
'required' => 'how about the email?',
'email' => 'how about the email format?',
],
];
Finally, at your messages() method call the lang's line of your package respectively:
public function messages(){
return [
'email.required' => trans('myPackage::validation.email.required'),
'email.emial' => trans('myPackage::validation.email.valid'),
];
}

How do you flash Request data if a Validator fails in Laravel 5?

I've created a simple contact form in Laravel 5, using the Request object and a Validator object to check my input for errors.
The form in my view is coded in HTML, rather than the Laravel Form object, which isn't included by default in Laravel 5.
I need to set up my form so that if a validation rule fails, the user's input is flashed to the session so it doesn't disappear when the page redirects. I was able to accomplish this by putting a $request->flash() in the POST controller, before the validation code.
However, I do not want the data to be flashed (i.e, the form should be reset) if the validation passes and the form is successfully emailed. There's no apparent way for me to accomplish this in the $this->validate block, since Laravel helpfully handles the redirects automatically.
How can I tell Laravel to flash the form data ONLY if there is a validation error?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class ContactController extends Controller
{
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return view('contact');
}
/**
* Store a newly created resource in storage.
*
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
// Flash current input in case the validator fails and redirects
$request->flash();
// Validate the form request, redirect on fail
$this->validate($request, [
'name' => 'required',
'email' => 'required|email',
'subject' => 'required',
'message' => 'required|min:5',
]);
// Generate email from template and send
\Mail::send('emails.feedback',
array(
'name' => $request->get('name'),
'email' => $request->get('email'),
'user_message' => $request->get('message'),
'subject' => $request->get('subject')
), function ($message) use ($request) {
$message->from(\Config::get('site.from_email'));
$message->to(\Config::get('site.contact_email'), 'Admin');
$message->subject(\Config::get('site.name') . ': ' . $request->get('subject'));
});
// Redirect to Contact route with success message
return \Redirect::route('contact')
->with('message', 'Thanks for contacting us!');
}
}
?>
If anybody like me didn't know how to get the old values and end up here somehow, here it goes:
<input value="{{ old('var_name') }}">
I don't see you needing to access the session data when Laravel provides you helpers like this.
Hope to have helped, have a nice day. =)
Just remove the following line of code:
$request->flash();
Laravel will take care of that for you by flashing the data on failed validation. The following method gets called on failed validation:
/**
* Create the response for when a request fails validation.
*
* #param \Illuminate\Http\Request $request
* #param array $errors
* #return \Illuminate\Http\Response
*/
protected function buildFailedValidationResponse(Request $request, array $errors)
{
if ($request->ajax() || $request->wantsJson()) {
return new JsonResponse($errors, 422);
}
return redirect()->to($this->getRedirectUrl())
->withInput($request->input()) // <-- Flashes inputs
->withErrors($errors, $this->errorBag()); // <-- Flashes errors
}
This is the trait used in your controller for validating the request and it's located at Illuminate/Foundation/Validation, name is ValidatesRequests. Check it to clarify yourself.
Alternatively, you may do it manually if you want for any reason, check the documentation.
To restore the old value if validation fails the entered data will display the view
value="{{ (old('title')) ? old('title') : $data->title}}

Categories