4

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?

kaan_a
  • 3,503
  • 1
  • 28
  • 52
  • That's very individual thing you need... you will probably have to write your own validation rule or use 'regex' validation rule – lewis4u Aug 10 '20 at 12:15

2 Answers2

3

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'
    ],
]);
Jonatan Lavado
  • 954
  • 2
  • 15
  • 26
1

There is no such built-in validation rule. You would need to create a custom validation rule (see docs). Use regex rule (see docs) to acheive it.

Nikolai Kiselev
  • 6,201
  • 2
  • 27
  • 37