Paulo Freitas
Paulo Freitas

Reputation: 13649

Laravel: custom multidimensional array validation

I've a form which user will insert many records at a time. Each record will have an id, a start date and an end date. To process the input data, I'm looking for the best way to validate all these things.

So I need some sort of multidimensional array validation here... Is there any custom validation plugin/code already coded for that?

I've tried to extend Laravel validation but I couldn't get even close to what I'd like...

What I've tried:

app/services/validators/LearningPathValidator.php (I'm using laravel-extended-validator)

<?php

use Crhayes\Validation\ContextualValidator;

class LearningPathValidator extends ContextualValidator
{
    protected $rules = [
        'default' => [
            'name'    => 'required|max:96',
            'courses' => 'required|multi_array:course_id=required;exists:courses,date_start=required;date_format:d/m/Y,date_end=required;date_format:d/m/Y'
        ],
    ];
}

app/validations.php (Here I'm extending Illuminate\Validation\Validator class)

<?php

class AppValidator extends Illuminate\Validation\Validator
{
    protected function validateMultiArray($attribute, $value, $parameters)
    {
        if (!is_array($value)) {
            return false;
        }

        foreach ($parameters as $parameter) {
            list($_attribute, $rules) = $this->parseRule(
                str_replace(['=', ';'], [':', ','], $parameter));

            foreach ($rules as $rule) {
                foreach (array_keys(Input::get($attribute)) as $idx){
                    $this->validate(sprintf('%s.%d.%s', $attribute, $idx,
                        snake_case($_attribute)), $rule);
                }
            }
        }

        return count($this->messages->all()) === 0;
    }
}

My start/global.php: (Here I extend Illuminate\Validation\Validator with AppValidator)

// ...

Validator::resolver(function($translator, $data, $rules, $messages) {
    return new AppValidator($translator, $data, $rules, $messages);
});

// ...

My models are using courses[$index][course_id], courses[$index][date_start] and courses[$index][date_end] as field names.

Actually I can't require at least one record as I said before and I can't assure end date will be older than start date. Any suggestions to rewrite what I've coded? Thank you in advance!

Upvotes: 4

Views: 4551

Answers (1)

sjdaws
sjdaws

Reputation: 3536

I created a package to do just this as I encountered the same problem with data from AngularJS.

https://github.com/lakedawson/vocal

Upvotes: 1

Related Questions