Search code examples
phplaravelvalidationscalar

Is there a Laravel validation rule that checks if a field is scalar


I am using Laravel's validator to validate a JSON request inside the controller:

class InsertProduct extends ModuleApiController
{
    public function handle(Request $request, int $fileId)
    {
        $data = $request->json()->all();

        $validator = Validator::make($data, [
            'products' => ['required', new ArrayWithType('seq', 'The :field field must be an array')],
            'products.*' => ['required', new ArrayWithType('assoc', 'The :field field must be an object')],
            'products.*.code' => 'required|alpha_num',
            'products.*.variants' => ['required', new ArrayWithType('seq', 'The :field field must be an array')],
            'products.*.variants.*' => ['required', new ArrayWithType('assoc', 'The :field field must be an object')],
            'products.*.variants.*.barcode' => 'required|alpha_num',
        ]);

The products.*.code fields and the products.*.variants.*.barcode fields can be things like:

20032199231
"AB3123-X"
"Z22.327p"
"001230572"
"Houston22"

I can't seem to find a rule that will accept all of these potential values but reject array or object (associative arrays once Laravel parses the JSON) values.

Things I've tried:

 Rule                 | Issue
----------------------|--------------------------------------------------------------------
'required'            | Will validate JSON objects and arrays 
'required|string'     | Won't validate integer values like the first one above
'required|alpha_num'  | Won't validate the middle three values above
'required|alpha_dash' | Won't validate values that contain periods (.) like the third one

What I need is something like: 'required|not_array' or 'required|scalar' but I haven't been able to find anything like that in the documentation.

Do I really have to write a custom validation rule for this?


Solution

  • Have you tried to do something like this? Using is_scalar

    $validator = Validator::make($request->all(), [
        'products.*.code' => [
            'required',
            function ($attribute, $value, $fail) {
                if (!is_scalar($value)) {
                    $fail($attribute.' isnt a scalar.');
                }
            },
        ],
    ]);
    

    Or, if you want to register your custom validation:

    public function boot()
    {
         Validator::extend('is_scalar', function ($attribute, $value, $parameters, $validator) {
             return !is_scalar($value);
         });
     }
    

    And then:

    $validator = Validator::make($request->all(), [
        'products.*.code' => [
            'required',
            'is_scalar'
        ],
    ]);