DEV Community

Ghulam Mujtaba
Ghulam Mujtaba

Posted on

Extraction of Form Validation Object and Authenticate Class

In our previous project, we learned how to login or logout a registered user. But today, we will learn how to extract a form validation object and about authenticate class extraction in the project.

On VS Code Side

To start the project, we need to add a new directory named Http, then move the controllers into this new directory. Next, we need to add another new directory in Http named Forms and add a new file LoginForm in this directory. Then, we need to run the project, which will show an error because the controllers have been moved to a new directory and their routes need to be updated in routes.php.

$router->get('/', 'index.php');
$router->get('/about', 'about.php');
$router->get('/contact', 'contact.php');
$router->get('/notes', 'notes/index.php')->only('auth');
$router->get('/note', 'notes/show.php');
$router->delete('/note', 'notes/destroy.php');
$router->get('/note/edit', 'notes/edit.php');
$router->patch('/note', 'notes/update.php');
$router->get('/notes/create', 'notes/create.php');
$router->post('/notes', 'notes/store.php');
$router->get('/register', 'registration/create.php')->only('guest');
$router->post('/register', 'registration/store.php')->only('guest');
$router->get('/login', 'session/create.php')->only('guest');
$router->post('/session', 'session/store.php')->only('guest');
$router->delete('/session', 'session/destroy.php')->only('auth');
Enter fullscreen mode Exit fullscreen mode

Extract Form Validation Object

To extract a form validation object, we need to go to session/store.php and cut the code that checks if the provided email and password are correct. We then need to move this code to the LoginForm.php file, which is located in the Http/Forms directory.

LoginForm

The LoginForm.php file will contain data related to user login to validate forms and protected errors array that points to errors in project

<? php
namespace Http\Forms;
use Core\Validator;
class LoginForm {
  protected $errors = [];
  public function validate($email, $password) {
    if (!Validator::email($email)) {
      $this->errors['email'] = 'Please provide a valid email address.';
    }
    if (!Validator::string($password)) {
      $this->errors['password'] = 'Please provide a valid password.';
    }
    return empty($this->errors);
  }
  public function errors() {
    return $this->errors;
  }
  public function error($field, $message) {
    $this->errors[$field] = $message;
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we can see that project is working well.

Extract Authenticate Class

Next , to extract an authenticate class, we need to select all code segments that are used to authenticate the user, such as checking the user's email and password. We then need to add a new file authenticator.php, which will contain an authenticate class used for user authentication then login and logout functions were imported.

<?ph
namespace Core;
class Authenticator {
  public function attempt($email, $password) {
    $user = App::resolve(Database::class)
      ->query('select * from users where email = :email', [ 'email' => $email ])
      ->find();
    if ($user) {
      if (password_verify($password, $user['password'])) {
        $this->login([ 'email' => $email ]);
        return true;
      }
    }
    return false;
  }
  public function login($user) {
    $_SESSION['user'] = [ 'email' => $user['email'] ];
    session_regenerate_id(true);
  }
  public function logout() {
    $_SESSION = [];
    session_destroy();
    $params = session_get_cookie_params();
    setcookie('PHPSESSID', '', time() - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
  }
}
Enter fullscreen mode Exit fullscreen mode

Update session store file

Further moving , We need to go back to session/store.php and initialize the $form and in for the new user login. We then need to implement an if condition to check if the form is valid or not. If the form is not valid, we have to redirect the user to the desired path.

<?php
use Core\Authenticator;
use Http\Forms\LoginForm;

$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.');
}
return view('session/create.view.php', [ 'errors' => $form
Enter fullscreen mode Exit fullscreen mode

By making these changes we can extract a authenticate class to change the look of our code means easy to understand and modify.

I hope that you have clearly understood it

Top comments (0)