1
votes

I have many different places in my app where a user can edit their data. More specifically, I need to validate the form with user data by starting off from registration (checking their username length, if some fields are required, etc) and checking their data when they are logging in (again checking their username length). In addition, when they are editing their profile, I need to check how many max characters their username can be, etc. This is just the beginning. If I have an admin panel, I need to do that there A moderation panel, I also need to do that there. And not just with username, maybe with their full name, avatar URL, etc.

I cannot create one request file for this because in registration, there are only about 4 fields while in login, there are 2 and in user account settings, there are like 10. So the request file needs to be different in all scenarios.

However, the validation rules, like username needs to be x characters and needs to be alphanumeric. And the password needs to be max x characters, etc. This is very repetitive across all the different request file.

How can I best sort this issue out without duplication all the validation rules?

A code example:

// LoginRequest.php

public function rules()
{
    return [
        'username' => 'required|max:16|min:6',
        'password' => 'required|max:16|min:6|alphanumeric'
    ];
}

// UserAccountSettingsRequest

public function rules()
{
    return [
        'username' => 'required|max:16|min:6|alphanumeric',
        'email'    => 'required|email',
        'name'     => 'required|max:100|min:2',
        'password' => 'required|max:16|min:6',
        'avatar'   => 'required|max:256'
    ];
}

// RegistrationRequest

public function rules()
{
    return [
        'username' => 'required|max:16|min:6|alphanumeric',
        'name'     => 'required|max:100|min:2',
        'email'    => 'required|email',
        'password' => 'required|max:16|min:6',
    ];
}

As you can see, I had to repeat many rules many times. How can I prevent this?

Thanks!

2

2 Answers

1
votes

To allow for additional rules, just make some modifications to the build function, for example:

<?php
namespace App\Helpers;

class ValidationRulesBuilder
{
    private static $validation_rules_preset = ["username" => "required|max:16|min:6|alphanumeric", "name" => 'required|max:100|min:2', 'email' => 'required|email', 'password' => 'required|max:16|min:6'];

    public static function buildValidationRules($fields)
    {
        $ret = [];
        foreach ($fields as $field) {
            $pos = strpos($field, '|');
            if ($pos !== false) {
                $ret[$field] = self::$validation_rules_preset[substr($field,0,$pos)]. substr($field, $pos);
            } else {
                $ret[$field] = self::$validation_rules_preset[$field] ;
            }
        }
        return $ret;
    }
}

Use it:

 public function rules()
     {
         return (\App\Helpers\ValidationRulesBuilder::buildValidationRules(['username|min:5|custom-validation','password']));
     }

password is the default rule, username is the default rule plus "min:5|custom-validation"

1
votes

Consider using the php array_merge() function.

You can refactor common validation rules into a new file, and autoload it with composer.json and composer dump-autoload. (PSR4 autoloading)

For example, in validation_rules.php, you can write:

$validation_rules_user_pwd=['username' => 'required|max:16|min:6|alphanumeric','password' => 'required|max:16|min:6'];

When you need to use it, you may do

public function rules()
 {
     return array_merge($validation_rules_user_pwd,[
              'email' => 'required|email',
              'name' => 'required|max:100|min:2|,
              'avatar' => 'required|max:256
            ]);
 }

To push it even further, you may write a helper function which takes in an array of strings and returns an associate array.

E.g.

<?php
namespace App\Helpers;

class ValidationRulesBuilder
{
    private static $validation_rules_preset = ["username" => "required|max:16|min:6|alphanumeric", "name" => 'required|max:100|min:2', 'email' => 'required|email', 'password' => 'required|max:16|min:6'];

    public static function buildValidationRules($fields)
    {
        $ret = [];
        foreach ($fields as $field) {
            $ret[$field] = self::$validation_rules_preset[$field];
        }
        return $ret;
    }
}

Then, use it with

 public function rules()
     {
         return (\App\Helpers\ValidationRulesBuilder::buildValidationRules(['username','password']));
     }