Laravel 8 Form Request Validation Redirect to Index page instead same page and show error - laravel

On localhost all is good, but when I deploy the application to the server not working. If form request validation fails instead of bringing me back to the same page and showing an error, it redirects me to the index page.
config.blade.php
<form method="POST" action="{{ route('config.update', $config->id) }}">
#csrf
#method('PUT')
<div class="form-group row">
<div class="col">
<label class="col-form-label">Name</label>
<input id="name" type="text" class="form-control" name="name" value="{{ $config->name }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Address</label>
<input id="address" type="text" class="form-control" name="address" value="{{ $config->address }}">
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Phone</label>
<input id="phone" type="tel" class="form-control" name="phone" value="{{ $config->phone }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">E-mail</label>
<input id="email" type="email" class="form-control" name="email" value="{{ $config->email }}" required>
</div>
</div>
<div class="form-group row mt-4 mb-0">
<div class="col-md-12">
<button type="submit" class="btn btn-primary button-full-width">Save changes</button>
</div>
</div>
</form>
web.php
Route::resource('/admin/config', 'Admin\ConfigController');
ConfigController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Services\ConfigServices;
use App\Http\Requests\ConfigRequest;
use App\Models\Config;
class ConfigController extends Controller
{
protected $configServices;
public function __construct(ConfigServices $configServices) {
$this->middleware('auth');
$this->configServices = $configServices;
}
...
public function update(ConfigRequest $request, $id)
{
$config = $this->configServices->updateConfigById($request, $id);
return redirect()->back();
}
...
}
ConfigRequest - here is the problem
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ConfigRequest 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
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
'address' => 'nullable|string|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:9|max:15',
'email' => 'required|email:rfc',
];
}
}
Form Request return to index page instead same page. On localhost working everything, but when I deploy the app to server a problem arises.
When data on form request validated correct return me back on the same page and show success, but when form request failing redirect mine for some reason to the index page.
A problem arises in Laravel 8, this code worked well in previous Laravel versions.
Can someone help me, please?

In your custom request you need:
/**
* The URI that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirect = '/dashboard';
or
/**
* The route that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirectRoute = 'dashboard';
You can find more in the docs.
In the docs for older versions of Laravel these properties don't exist.

Do you have error parts in your blade?
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#if ($message = Session::get('unique'))
asdsad
#endif
#endforeach
</ul>
</div>
#endif

Related

Laravel: Display of validation errors not shown

I'm having a problem viewing validation errors in the blade view; this is the code below.
Controller (ClientController)
public function store(Request $request) {
$request->validate([
'name' => 'required',
'surname' => 'required',
'diagnosis' => 'required',
]);
Client::create([
'name'=>$request->name,
'surname'=>$request->surname,
'city'=>$request->city,
'diagnosis'=>$request->diagnosis,
]);
return redirect(route('client.index'))->with('message','The customer was successfully saved');
}
View (client.create)
<x-layout>
<div class="container">
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form action="{{route('client.store')}}" method="post">
#csrf
<div class="row mt-3">
<div class="col-12 col-md-6">
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control p-3" name="name" required>
</div>
<div class="mb-3">
<label for="surname" class="form-label">Cognome</label>
<input type="text" class="form-control p-3" name="surname" required>
</div>
<div class="col-12">
<div class="mb-3">
<label for="diagnosis" class="form-label">Diagnosi</label>
<input type="text" class="form-control p-3" name="diagnosis" required>
</div>
</div>
<button type="submit" class="btn btn-primary mb-5 py-3 px-5 mt-3 ms-3">Add</button>
</div>
</div>
</form>
</div>
</x-layout>
I have followed the documentation but am unable to understand where the problem is.
Laravel documentation
Thanks to those who will help me
CONTROLLER UPDATE:
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('client.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'surname' => 'required',
'diagnosis' => 'required',
]);
//dd($request->all());
Client::create([
'name'=>$request->name,
'surname'=>$request->surname,
'city'=>$request->city,
'diagnosis'=>$request->diagnosis,
'stay'=>$request->stay
]);
return redirect(route('client.index'))->with('message','The customer was successfully saved');
}
Index is a blade view that contains the customer table (this works fine).
The problem is the error messages I would like to see in the create view if an input is required and not compiled
So after checking all components, it has been under our nose the whole time.
All your inputs have the required attribute:
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control p-3" name="name" required>
</div>
<div class="mb-3">
<label for="surname" class="form-label">Cognome</label>
<input type="text" class="form-control p-3" name="surname" required>
</div>
<div class="col-12">
<div class="mb-3">
<label for="diagnosis" class="form-label">Diagnosi</label>
<input type="text" class="form-control p-3" name="diagnosis" required>
</div>
</div>
This way the request is not sent, because the browser actively needs to fulfil all requirements to start the request to client.create
If you would remove one of these attributes and then not fill it in and submit, it will cause the errors to show.
However, we concluded that it is better to keep the required attribute in, as it is better to prevent a call to the webserver than to only let laravel do the work of validation.
The laravel validation is more useful for ajax/api calls, where there is no frontend to prevent you from making the request, like this:
//required jquery
$.ajax({
url: '/your/url/here',
method: 'POST',
data: [
name: 'somename',
surname: 'somesurname',
],
success(response) {
console.log('Yay, it succeeded')
},
error(error) {
//I havent worked with jquery in a while, the error should be in error object
console.log(error);
}
})
Or how I like to do it in vue, with axios:
//requires axios
axios
.post('/url/here', {
surname: 'somesurname',
diagnosis: 'somediagnosis',
})
.then(response => {
console.log('Yay, it succeeded')
})
.catch(error => {
console.log('Error', error)
})
You can see in the last two examples, as there is no frontend to prevent this request from being made, you now at least make sure laravel is not going to run it's logic with missing variables, which would cause a crash.

Laravel 5.8 authentication

Hi i've a problem with laravel authentication system (5.8) The problem is that I need to login two times to enter my site
My routes file is
Route::get('/', 'RefundsController#index');
Route::get('/polizza', 'RefundsController#indexRefunds')->name('polizza');
Auth::routes();
--------------other routes------------------
RefundsController
public function __construct()
{
$this->middleware('auth');
}
public function index(){
return view('auth.login');
}
public function indexRefunds(Request $request){
DB::enableQueryLog();
$grafici = 1;
$getAverageLiquidati = DB::table('refunds')
->select(DB::raw("AVG(DATEDIFF(date_liq, date_ref)) AS avgliq"))
->where([
['disactive','=', 1],
['date_liq','<>','0000-00-00'],
['status_ref','>', 5]
])
->get();
$getAverageRifiutati = DB::table('refunds')
->select(DB::raw("AVG(DATEDIFF(date_status, date_ref)) AS avgrif"))
->where(function($q) {
$q->where('status_ref','=', 2)
->orWhere('status_ref','=', 3)
->orWhere('status_ref','=', 4);
})
->where([
['disactive','=', 1],
['date_liq','<>','0000-00-00'],
])
->get();
//dd(DB::getQueryLog());
//dd($getAverageRifiutati);
return view('pages.modify', compact('grafici','getAverageLiquidati','getAverageRifiutati'));
}
login blade
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
#csrf
<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') }}" required autocomplete="email" autofocus>
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control #error('password') is-invalid #enderror" name="password" required autocomplete="current-password">
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<!--<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{-- old('remember') ? 'checked' : '' --}}>
<label class="form-check-label" for="remember">
{{-- __('Remember Me') --}}
</label>
</div>
</div>
</div>-->
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
{{--#if (Route::has('password.request'))--}}
<!--<a class="btn btn-link" href="{{-- route('password.request') --}}">
{{-- __('Forgot Your Password?') --}}
</a>-->
{{--#endif--}}
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
my LoginController
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 = '/polizza';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
In my Middleware
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/polizza');
}
return $next($request);
}
}
When i connect to https://www.example.com/refunds/ because of definition in RefundsController it takes me to https://www.example.com/refunds/login but when i insert credentials it takes me to https://www.example.com/refunds/ with again login form then when i insert credentials it finally takes me to https://www.example.com/refunds/polizza
I dont understand why :(
The first redirect happens because in your Controller constructor, you are setting the middleware to auth. Hence, all unauthorized requests to any methods in that Controller will be redirected to default log in page. (https://www.example.com/refunds/ redirects to https://www.example.com/refunds/login)
When you enter your credentials there, Laravel takes you to your intended route (the route you tried to access without being authenticated, and that is https://www.example.com/refunds/).
This time you are authenticated, so in your controller, your index method is set to return log in view, so the view is being returned and rendered, and the form is being shown for the second time now. Now, that you log in for the second time, the Log In controller will redirect you to https://www.example.com/refunds/polizza, as there intended route does not exists, and it uses the default route which is correctly set to /polizza.
How to resolve this issue?
In your controller's constructor, change the line with:
$this->middleware('auth')->except(['index']);
This way, you will exclude the index function from the auth middleware and it can be accessible to the public. The request should no longer redirect you to the default log in page. Now, going to https://www.example.com/refunds/ will just render a log in form, as you specified in your controller. When you log in with that form, it will take you to /polizza route.

middleware conflicts with controller __construct middleware (request validation error not working)

I am using middleware for user roles.
But when I am using middleware in Controller __construct method, request validation does not work properly. It doesnt show any errors, session error bag returns null. I am not able to see any errors when form submit. But when I have disabled middleware in construct I can see request validation errors.
web.php middleware + controller _construct middleware = request validation doesnt works.
web.php middleware + without _construct middleware = works fine.
without web.php middleware + _construct middleware = works fine.
I showed the details in my codes.
I tried every method for a week but I couldn't solve it.
I look forward to your help sincerely.
web.php
Route::group(['middleware' => ['client.role:paying']], function () {
Route::get('/pay_section', 'HomepageController#showPaySection');
Route::get('/pay_success', 'HomepageController#showPaySuccess');
Route::get('/pay_error', 'HomepageController#showPayError');
Route::post('/pay_section', 'HomepageController#doPaySection');
});
HomepageController (like this my form request validation doesnt works because of middleware)
public function __construct()
{
$this->middleware(function ($request, $next) {
$client = auth()->guard('client');
if ($client->check()){
$request->session()->put('client_id', $client->user()->id);
}else{
$request->session()->put('client_id', -1);
}
$this->_cid = $request->session()->get('client_id'); // client
View::share(['cid' => $this->_cid]);
return $next($request);
});
}
HomepageController (like this my codes works perfect. I am able to see request validation errors there is no problem.)
public function __construct()
{
$this->_cid = 2; // client
View::share(['cid' => $this->_cid]);
}
Middleware ClientRole.php
public function handle($request, Closure $next, ...$roles)
{
$currentRole = array();
$client = auth()->guard('client');
if ($client->check()){
$currentRole[] = 'client';
}else{
$currentRole[] = 'guest';
}
if (session()->has('shop_cart')) {
$currentRole[] = 'shopping';
}
if (session()->has('order')) {
$currentRole[] = 'paying';
}
$currentRole[] = 'paying';
foreach($roles as $role) {
if(in_array($role, $currentRole))
return $next($request);
}
return redirect('/');
}
HomepageController form action
public function doPaySection(CreditcardRequest $request)
{
$validated = $request->validated();
// it doesnt show any errors when form empty. But it should be.
// without middleware it shows error on my view when form empty.
}
View
<div class="messages">
#if ($errors->any())
<div class="row mt-3">
<div class="col-md-12">
<div class="alert alert-warning alert-dismissable" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h3 class="alert-heading font-size-h4 font-w400">Error!</h3>
#foreach ($errors->all() as $error)
<p class="mb-0">{{ $error }}</p>
#endforeach
</div>
</div>
</div>
#endif
</div>
<form action="{{ action('HomepageController#doPaySection') }}" method="post"
class="needs-validation" novalidate>
#csrf
<div class="row">
<div class="col-md-6 mb-3">
<label for="ccname">Name on card</label>
<input type="text" class="form-control" name="cc_name" id="ccname" placeholder="" value="" required>
<small class="text-muted">Full name as displayed on card</small>
<div class="invalid-feedback">
Name on card is required
</div>
</div>
<div class="col-md-6 mb-3">
<label for="ccnumber">Credit card number</label>
<input type="text" class="form-control" name="cc_number" id="ccnumber" placeholder="" value="" >
<div class="invalid-feedback">
Credit card number is required
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<label for="ccexp">Expiration</label>
<input type="text" class="form-control" name="cc_exp" id="ccexp" placeholder="" value="1209" required>
<div class="invalid-feedback">
Expiration date required
</div>
</div>
<div class="col-md-3 mb-3">
<label for="cccvv">CVV</label>
<input type="text" class="form-control" name="cc_cvv" id="cccvv" placeholder="" value="333" required>
<div class="invalid-feedback">
Security code required
</div>
</div>
</div>
<hr class="mb-4">
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit">
<i class="fa fa-check"></i> Submit
</button>
</form>
You may set SESSION_DRIVER=file in you .env file
Then run php artisan config:clear
Seems related

Prevent login if user isnt approved laravel 5.4

I checked all around for information about how to check on login if user is approved or not and then redirect to logged in or give an error. Now i am little confused because in internet there are a lots of posts and every one is different. So can anyone can help me to deal with this? Also it would be really nice to explain how it works (sintaxes and all other stuff)
User.php:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'companyname', 'email', 'password', 'VAT', 'companyphone',
'companystreet', 'companycity', 'companycountry', 'companypostcode'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
LoginController :
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 = '/';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
login.blade.php :
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Login</div>
<div class="panel-body">
#if($status = Session::get('status'))
<div class ="alert alert-info">
{{$status}}
</div>
#endif
<form class="form-horizontal" method="POST" action="{{ route('login') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="{{ route('password.request') }}">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
#endsection
Also in my DB is boolean field "activated" default 0
#Karlis Pokkers
Middleware is one option but, I would like to go for little hack provided by Laravel documentation.
You can override Laravel's attemptLogin method.
Add this code to your app > Http > Controllers > Auth > LoginController:
/**
* Attempt to log the user into the application.
*
* #param \Illuminate\Http\Request $request
* #return bool
*/
protected function attemptLogin(Request $request)
{
return Auth::attempt(['username' => $request->username, 'password' => $request->password, 'activated' => 1 ]);
}
No need to write you own LoginController. Use Laravel's default authentication Controllers.
You can check out different sites for that. Answer on Laracast
With laravel its very simple. You have to create a new middleware or extend the app/Http/Middleware/RedirectIfAuthenticated.php middleware.
A good documentaion you can find here: https://laravel.com/docs/5.5/middleware
For example:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::user()->activated) {
return redirect('/home');
}
return $next($request);
}

Issues with Laravel Mailables

I'm trying to create a contact form in Laravel using Laravel 5.3, but I get this nasty error here:
ErrorException in helpers.php line 519:
htmlspecialchars() expects parameter 1 to be string, object given (View: /Applications/XAMPP/xamppfiles/htdocs/meps/resources/views/emails/contactemail.blade.php)
Here are the files that I was using:
The contact form
<div class="contact-form">
<form class="margin-clear" role="form" action="{{ url('/sendmail') }}" method="POST">
{{ csrf_field() }}
<div class="form-group has-feedback">
<label for="name">Name*</label>
<input type="text" class="form-control" id="name" name="name" placeholder="">
<i class="fa fa-user form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="email">Email*</label>
<input type="email" class="form-control" id="email" name="email" placeholder="">
<i class="fa fa-envelope form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="subject">Subject*</label>
<input type="text" class="form-control" id="subject" name="subject" placeholder="">
<i class="fa fa-navicon form-control-feedback"></i>
</div>
<div class="form-group has-feedback">
<label for="message">Message*</label>
<textarea class="form-control" rows="6" id="message" name="message" placeholder=""></textarea>
<i class="fa fa-pencil form-control-feedback"></i>
</div>
<input type="submit" value="Submit" class="btn btn-primary">
</form>
</div>
The Controller function
public function sendmail(Request $request, Mailer $mail) {
$mail->to('kaley36_aw#yahoo.com')->send(new ContactEmail($request->name, $request->email, $request->subject, $request->message));
$request->session()->flash('mail-sent', 'Your email has been sent.');
return redirect('/contact');
}
The Mailable class
class ContactEmail extends Mailable
{
use Queueable, SerializesModels;
public $name;
public $email;
public $subject;
public $message;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($name, $email, $subject, $message)
{
$this->name = $name;
$this->email = $email;
$this->subject = $subject;
$this->message = $message;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from($this->email)->view('emails.contactemail');
}
}
And here is the route
Route::post('sendmail', 'EmailController#sendmail');
You probably looking at the wrong view. The error points to
/views/emails/contactemail.blade.php
But this view has a <form> unless you are sending back to your users a form via e-mail, this looks a lot more like your contact form view and not your e-mail view. Something like:
/views/contact.blade.php (or whatever you have in there as a form)
As for the error, you must have a {{ $variable or functionCall() }} which is not receiving a string, but an object.
I figured it out. The issue was with the variable $message, Laravel wrapped it in an actual object called Message. All I had to do was change the variable name to $theMessage and it worked find.

Resources