PHP Validation library to use with ATK?


#1

Can you suggest a validation framework?

ATK allows using arbitrary frameworks for validating values (http://agile-ui.readthedocs.io/en/latest/form.html?highlight=validate#validating), but which 3rd party validation framework you would recommend and why?


#2

I have made a simple integration with https://github.com/vlucas/valitron, here is how:

First - i’m redefining the \atk4\data\Model class. I’m doing it anyway and all the models in my project extend MyModel:

class MyModel extends \atk4\data\Model
{
    function init()
    {
        parent::init();
        $this->_default_seed_addField = ['\MyModelField'];
    }

    function validate($intent = null) {
        $v = new \Valitron\Validator($this->get());

        foreach($this->elements as $key=>$field) {
            if (!$field instanceof \saasty\ModelField) {
                continue;
            }
            $field->validate($v);
        }

        if ($v->validate()===true) {
            return parent::validate($intent);
        }
       

        $errors = parent::validate($intent);

        foreach($v->errors() as $key=>$e){ 
            if (!isset($errors[$key])) {
                $errors[$key] = array_pop($e);
            }
        }

        return $errors;
    }
}

I had to pop only the first error, because ATK forms don’t display multiple errors per field. Next I need to declare MyModelField also:

class MyModelField extends \atk4\data\Field_SQL
{
    /**
     * Describes arbitrary validation rules
     */
    public $validate = [];

    function validate($v) {
        if ($this->validate) {
            if (is_array($this->validate)) {
                foreach($this->validate as $k=>$v) {
                    $v->rule($k, $this->short_name, $v);
                }
            } else {
                $v->rule($this->validate, $this->short_name);
            }
        }
    }

}

That’s all. To define validation now, I can use:

$model->addField('email', ['validate'=>'email']);
$model->addField('age', ['validate'=>['min'=>18]]);

I hope this helps!