Automatically Redirect Back Upon Failed Validation
Ghulam Mujtaba
Posted on July 12, 2024
Form validation refactoring
Once again back into same controller that handles logging in user. In this I will point your attention to all about form validation. Let in future when you want to create multiple forms in your application then you may to intensitiate the form, validation, event and duplicate part of code to give back the last submitted form and redirects it to desired page in every single controller if you work using this file.
$email = $_POST['email'];
$password = $_POST['password'];
$form = new LoginForm();
if ($form->validate($email, $password)) {
if ((new Authenticator)->attempt($email, $password)) {
redirect('/');
}
$form->error('email', 'No matching account found for that email address and password.');
}
Session::flash('errors', $form->errors());
return redirect('/login');
According to this firstly we are creating a new form then validating it. To refactor this we have to remove first grab out parameters of first if conditional and remove the conditional. then we have to inline new form and validate statement as:
LoginForm::validate($email, $password);
LoginForm class
Let's see if it can work , go to to LoginForm change the public function validate() to public static function validate () the all data inside it becomes static constructor then create a _construct method that can accept email and password in single form only $attribute, also validate method can accept an array of attributes then to move up to static construct method .
protected $errors = [];
public function __construct($attributes)
{
if (!Validator::email($attributes['email'])) {
$this->errors['email'] = 'Please provide a valid email address.';
}
if (!Validator::string($attributes['password'],100 )) {
$this->errors['password'] = 'Please provide a valid password.';
}
}
public static function validate($attributes)
{
$instance = new static($attributes);
if($instance->failed()){
throw new ValidationException();
}
return $instance;
Calling _construct method
So that when I call a static constructor firstly have to intensiate a class with dedicated instance, count errors If any validation fails throw new exception in LoginForm.php as 'throw new /Exception but we are using ValidationException class so:
public static function validate($attributes)
{
$instance = new static($attributes);
if($instance->failed()){
throw new ValidationException();
}
return $instance;
Try-catch block
When we run the it shows errors that $form is not accessible to fix this issue we have to wrap it in try and catch method as :
try {
$form = LoginForm::validate($attributes = [
'email' => $_POST['email'],
'password' => $_POST['password']
]);
} catch (ValidationException $exception) {
Session::flash('errors', $form->errors());
Session::flash('old', [
'email' => $attributes['email']
]);
return redirect('/login');
}
Try checks either the to create a new form that accepts email and password, while catch method catches the data to check validation.
ValidationException class
At this stage Validation Exception file is empty so the errors are not accessible and the last submitted form is not showing to user. To solve this issue using ValidationException class directory in this we have to intialize the errors and password as public read-only array as there value is one time declare by user and is not updated .
namespace Core;
class ValidationException extends \Exception
{
public readonly array $errors;
public readonly array $old;
public static function throw($errors, $old){
$instance = new static;
$instance-> errors = $errors;
$instance->old=$old;
throw $instance;
;
}
}
Now you can check the project is working well and everything showing on output screen.
I hope that you have been clearly
Understood it.
Posted on July 12, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 14, 2024