Laravel 6 - login with Phone or Email - laravel-6

I'm using Laravel 6 and want user can alternatively login by email or mobile.
My attempts so far:
Migration is working fine.
Registration is working fine
Login works fine one at a time either email or mobile with below changes in loginController.php.
public function username()
{
return 'mobile'; // or email
}
and also
login.blade.php for HTML forms from email to mobile.
I tried to validate both email and phone by #error directive, like #error('email') || #error('mobile') is-invalid #enderror but no action after submit. below is the example
<input id="user_login" type="text" class="form-control #error('email') || #error('mobile') is-invalid #enderror" name="user_login" value="{{ old('user_login') }}" required autocomplete="user_login" autofocus>
#error('user_login')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
Your help will be appreciated.

change User migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->string('username')->unique()->nullable();
$table->string('mobile_number')->unique()->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
change User model:
protected $fillable = [
'name', 'email', 'password', 'mobile_number'
];
in app\Http\Controllers\Auth\RegisterController.php change:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'mobile_number' => $data['mobile_number'],
'password' => Hash::make($data['password']),
]);
}
then change your register and login views and add a field to get mobile_number

The provided blade template contains incorrect blade syntax that gets transformed to invalid php(the || is converted to plain text instead of the OR operation).
Checkout the resulting php below:
This can be fixed by using the #error and enderror twice:
<form action="{{ route('test.store') }}" method="post">
<input id="user_login" type="text" class="form-control #error('email') is-invalid #enderror #error('mobile') is-invalid #enderror" name="user_login" value="{{ old('user_login') }}" required autocomplete="user_login" autofocus>
#error('user_login')
To add an additional field for authenticating the following can be used:
resources/auth/login.blade.php
<form method="POST" action="{{ route('login') }}">
#csrf
<div class="form-group row">
<label for="phone" class="col-md-4 col-form-label text-md-right">{{ __('Phone') }}</label>
<div class="col-md-6">
<input id="phone" type="text" class="form-control #error('phone') is-invalid #enderror" name="email" value="{{ old('phone') }}" required autocomplete="email" autofocus>
#error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control #error('email') is-invalid #enderror" name="email" value="{{ old('email') }}" autocomplete="email" autofocus>
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
app/Http/Auth/LoginController.php
Overriding the username() method to use phone if provided and email as fallback.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return request()->has('phone') ? 'phone' : 'email';
}
}
or with a single field:
<div class="form-group row">
<label for="user_identifier" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address/Phone') }}</label>
<div class="col-md-6">
<input id="user_identifier" type="text" class="form-control #error('user_identifier') is-invalid #enderror" name="user_identifier" value="{{ old('user_identifier') }}" autofocus>
#error('user_identifier')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
and the associated LoginController method:
public function username()
{
$identifier = request()->get('user_identifier');
if(filter_var($identifier, FILTER_VALIDATE_EMAIL)){
return 'email';
}
return 'phone';
}

Related

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'county_id' cannot be null

I am trying to save my data from a dynamic selected dropdown into my database but I'm having errors doing so.
This is the error I am getting.
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'county_id' cannot be null (SQL: insert into `properties` (`National_id`, `Plot_No`, `Property_Ad`, `Property_Photo`, `Property_features`, `county_id`, `sc_id`, `town_id`, `type`, `updated_at`, `created_at`) values (63636, 424545, Duplex Apartments, test.jpg, Free parking, ?, ?, ?, ?, 2023-02-18 09:42:30, 2023-02-18 09:42:30))
I need help on how to save a selected drop down to a database which is a foreign key referencing another table (county_id references id on the county table, sc_id references id on the subcounty table and town_id references id on the town table).
This is my livewire page.
<form id="add-property-form" method="POST" action="{{URL::to('saveProperty')}}">
#csrf
<div class="col-md-8">
<div class="card">
<div class="card-body">
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li class="text-white">{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<div class= "form-group">
<!--input pattern= "[a-zA-Z]{2,10}$" required-->
<p>National id</p><input type="number" required name="National_id" value="{{old('National_id')}}" class="form-control #error('National_id') is-invalid #enderror"
placeholder="Confirm your National id number">
<div class="invalid-feedback">
#error('National_id') {{$message}} #enderror
</div>
<p>Plot No</p><input type="number" required name="plot_no" value="{{old('plot_no')}}" class="form-control #error('plot_no') is-invalid #enderror"
placeholder="Please enter plot number">
<div class="invalid-feedback">
#error('plot_no') {{$message}} #enderror
</div>
<p>Property Description</p><input type="text" required name="Property_Ad" value="{{old('Property_Ad')}}" class="form-control #error('Property_Ad') is-invalid #enderror"
placeholder="Please enter property description">
<div class="invalid-feedback">
#error('Property_Ad') {{$message}} #enderror
</div>
<p>Property Features</p><input type="text" required name="Property features" value="{{old('Property_features')}}" class="form-control #error('Property_features') is-invalid #enderror"
placeholder="Please enter property features">
<div class="invalid-feedback">
#error('Property_features') {{$message}} #enderror
</div>
<p>Property Images</p><input type="file" required name="Property_Photo" value="{{old('Property_Photo')}}" class="form-control"
>
<p>Location</p>
<div class="row align-items-start">
<div class="col">
<select id="County" class="form-select-lg mb-3 form-control" wire:model = "selectedCounty" name="County">
<option value="" >County</option>
#foreach ($counties as $co)
<option value="{{$co->id}}">{{$co->name}}</option>
#endforeach
</select>
</div>
#if (!is_null($subcounty))
<div class="col">
<select id="subCounty" class="form-select-lg mb-3 form-control" wire:model = "selectedSubCounty" name="subCounty">
<option value="">SubCounty</option>
#foreach ($subcounty as $su)
<option value="{{$su->id}}">{{$su->name}}</option>
#endforeach
</select>
</div>
#endif
#if (!is_null($town))
<div class="col">
<select id="Town" class="form-select-lg mb-3 form-control" wire:model = "selectedTown" name="Town">
<option value="">Town</option>
#foreach ($town as $to)
<option value="{{$to->id}}">{{$to->name}}</option>
#endforeach
</select>
</div>
#endif
</div>
<p>Property Type</p><input type="text" required name="property_type" value="{{old('type')}}" title="2-10 characters" class="form-control #error('type') is-invalid #enderror"
placeholder="Please enter your property type">
<div class="invalid-feedback">
#error('type') {{$message}} #enderror
</div>
</div>
<input type="submit" name="submit" class="form-control btn btn-success" >
</div>
</div>
</div>
</div>
</form>
This is my view page
#extends('layout')
#section('headTitle', 'Your Properties / Add Property')
#section('pageTitle', 'Your Properties / Add Property')
#section('content')
<livewire:subcounty />
#endsection
This is my controller page.
<?php
namespace App\Http\Controllers;
use App\Models\home_owners;
use App\Models\property;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class ProController extends Controller
{
public function viewProperties(){
$allPros = property::paginate(7);
//dd is the laravel version of var_dump() & die();
//dd($allRoles);
return view('HO.properties', ['properties'=>$allPros]);
}
public function addProperty(){
return view('HO.addproperty');
}
public function saveProperty(Request $request){
$prop = new property();
$prop->National_id=$request->National_id;
$prop->Plot_No=$request->plot_no;
$prop->Property_Ad=$request->Property_Ad;
$prop->Property_Photo=$request->Property_Photo;
$prop->Property_features=$request->Property_features;
$prop->county_id=$request->county_id;
$prop->sc_id=$request->sc_id;
$prop->town_id=$request->town_id;
$prop->type=$request->type;
if($request->hasFile('Property_photo')){
$file = $request->file('Property_photo');
$extension = $file->getClientOriginalExtension();
$filename = time().'.'.$extension;
$file->move('uploads/properties', $filename);
$prop->Property_Photo = $filename;
}
$prop->save();
return redirect('properties')->with('status',"New Property added.");
}
public function editProperty(){
}
}
basically it is indicating that the county_id field is being sent empty or null to the database, in your form the county_id field is called County, you need to change it:
<select id="County" class="form-select-lg mb-3 form-control" wire:model = "selectedCounty" name="County">
to
<select id="County" class="form-select-lg mb-3 form-control" wire:model = "selectedCounty" name="county_id">

after I fixed the error Route [Login] not defined, I can't log in even though I use the correct email and password

this is web.php
Route::get('/login', [LoginController::class, 'index'])->name('login')->middleware('guest');
Route::post('/login', [LoginController::class, 'authenticate']);
Route::post('/logout', [LoginController::class, 'logout']);
this is my LoginController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function index()
{
return view('login.index', [
'title' => 'Login'
]);
}
public function authenticate(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email:dns',
'password' => 'required'
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('/admin');
}
return back()->with('loginError', 'Login anda gagal !');
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/login');
}
}
this is my login view
<main class="form-signin">
#if (session()->has('Sukses'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ session('Sukses') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
#endif
#if (session()->has('loginError'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ session('loginError') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
#endif
<form action="/login" method="post">
#csrf
<img class="mb-4" src="/img/discord.png" alt="" width="100" height="99">
<h1 class="h3 mb-3 fw-normal">Please Login</h1>
<div class="form-floating">
<input type="email" name="email" class="form-control #error('email') is-invalid #enderror" id="email" placeholder="name#example.com" autofocus required value="{{ old('email') }}">
<label for="email">Masukkan Email</label>
#error('email')
<div class="invalid-feedback">
{{ $message }}
</div>
#enderror
</div>
<div class="form-floating">
<input type="password" name="password" class="form-control" id="password" placeholder="Password" required>
<label for="password">Password</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Login</button>
</form>
<small class="d-block text-center mt-3">Not have any account? Register here</small>
<p class="mt-5 mb-3 text-muted">© 2022</p>
</main>

Button for update function not working laravel 8 (CRUD)

I'm new to laravel 8. I try to make an update function controller when user already edit their data and store it in database. I try to click submit button and it's not working without any reason when i try to inspect at chrome. So i try another way which is comment the $request->validate and it's only change for name data while organisation_id leave blank and return to NULL. I wonder do we need to always validate the data in update function ?
Here is my Controller
public function edit($id)
{
$record = User::find($id);
$org = Organisation::all();
$t = Organisation::pluck("name");
return view ('user.edit',compact('record','org','t'));
}
public function edit_store(Request $request, $id)
{
$request->validate([
'name' => 'required',
'organisation_id' => 'required',
]
);
$record= User::find($id);
$record->name = $request->name;
$record->organisation_id = $request->organisation_id;
$record->save();
return redirect ('user')->with('success', 'Thank you');
}
Here is my edit blade
<div class="card">
<div class="card-body">
<form action="{{route('user_edit_store1', $record->id)}}" method="POST">
#csrf
<input type="hidden" name="id" value="{{ $record->id }}">
<div class="form-group row">
<label for="name"
class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text"
class="form-control #error('name') is-invalid #enderror" name="name"
value="{{ old('name') ? old('name') : $record->name }}"
</div>
</div>
<div class="form-group row">
<label for="organisation_id"
class="col-md-4 col-form-label text-md-right">{{ __('Organisation') }}</label>
<div class="col-md-6">
{!! Form::open(['route' => 'user_store']) !!}
{!! Form::select('id', $t, 'id', ['class' => 'form-control']) !!}
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary" >
{{ __('Save') }}
</button>
</div>
</div>
</form>
</div>
</div>
Routes
Route::get('user_edit/{id}',[UserController::class,'edit'])->name('user_edit');
Route::post('user_edit_store/{user}',[UserController::class,'edit_store'])->name('user_edit_store1');
Model user.php
protected $fillable = [
'name',
'organisation_id',
];
It appears that the <select> that you're creating with the Form::select form helper will have name of 'id' instead of 'organisation_id' which will result in a validation fail.

drop down select field stays null Livewire

I'm trying out Livewire for the first time. The drop-down is populated from the database. Similar codes works for text fields, but fails with drop-down select fields.
Edit: The form is inside a bootstrap modal
Code is as below: The livewire component (leads-form.blade)
<div class="modal-content">
<form wire:submit.prevent="submit">
#csrf
<div class="input-field col s12">
<label for="role">Client</label>
<select class="error validate" wire:ignore id="client_id" wire:model="client_id">
<option disabled value=" ">Client</option>
#foreach($clients as $client)
<option value="{{$client->id}}"> {{$client->clientname}}</option>
#endforeach
</select>
</div>
<div class="input-field col m12 s12">
<input id="contactperson" type="text" name="contactperson" wire:model="contactperson" />
#error('contactperson') <span class="error"><small>{{ $message }}</small></span> #enderror
<label for="contactperson">Contact Person</label>
</div>
<div class="row">
<div class="row">
<div class="input-field col s12">
<button class="btn cyan waves-effect waves-light right" type="submit">Add
<i class="material-icons right">send</i>
</button>
</div>
</div>
</div>
</form>
</div>
Next Livewire leads class is as a below:
class LeadsForm extends Component
{
public $contactperson;
public $client_id;
public function submit()
{
Lead::create([
'client_id' => $this->client_id,
'contactperson' => $this->contactperson,
]);
Alert::toast('Client created successfully', 'success');
return $this->redirectRoute('leads.index');
}
public function render()
{
$clients = Client::all();
return view('livewire.leads-form',[
'clients'=>$clients,
]);
}
}
I'm using the laravel debugbar, and it shows the array client_id field as null.
Remove the wire:ignore in the select element, that avoid produce any Livewire event that can be wrapped to backend
<select class="error validate" wire:ignore id="client_id" wire:model="client_id">
<option disabled value=" ">Client</option>
#foreach($clients as $client)
<option value="{{$client->id}}"> {{$client->clientname}}</option>
#endforeach
</select>

Laravel 5 authentication on home page

I have tried authentication before, but it has always been with views in my auth folder. I am now doing something different and cant seem to get it working. So I have this route which displays my homepage
Route::get('/', function () {
return view('index');
});
On my homepage, I have my register and login forms. I wont show everything, but my register form looks like the following
<form class="form-horizontal" role="form" method="POST" action="/">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<div class="col-md-12">
<input type="text" class="form-control" name="first_name" value="{{ old('first_name') }}" placeholder="First Name">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="text" class="form-control" name="last_name" value="{{ old('last_name') }}" placeholder="Last Name">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="email" class="form-control" name="email" value="{{ old('email') }}" placeholder="Email">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" class="form-control" name="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="password" class="form-control" name="password_confirmation" placeholder="Confirm Password">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-primary">
Register
</button>
</div>
</div>
</form>
I then tried adding my routes for the registration
Route::get('/register', 'Auth\AuthController#getRegister');
Route::post('/register', 'Auth\AuthController#postRegister');
Because this is using the built in authentication, looking at the Traits, things like getRegister return a view in the auth folder. So in my AuthController, I have added
public function getRegister()
{
return view('/');
}
However, if I try to register, I still get a MethodNotAllowedHttpException.
What would be the stages I need to go through in order to get registration and login onto my homepage?
Thanks
Be careful with the action of your form. You action is "/" but you registered the route Route::post('/register'....
So, your action for the form must be: action="/register"
It is going to make the request in the right rout.
Hope it helps.
PS: Check this course: Learn Laravel. There are explained step-by-step some concepts like this.
Best wishes.