Cygnite - A Modern Toolkit For Web Developers

The Elegant Way of Building Full-Featured Web Applications

Cygnite Dynamic Routing

Validator

Documentation

Form Validator

Introduction

Cygnite provides convenient way of validating user inputs and retrieving error message if validation fails. Cygnite offers various way of validating user inputs, you may use Model class, Cygnite\Database\Cyrus\ValidationTrait or Cygnite\Validation\Validator instance for validation. In this section we will demonstrate various features offered by Validator class and also will have a look at simple example for validating inputs, displaying error messages in the browser.

Creating Validator Instance

Creating validator instance to add rules, running validation against incoming data is just simple. You may use create method to get Validator instance or closure callback as below.

 
  

 use Cygnite\Validation\Validator;

 $input = Input::make();
 $post = $input->post();

 $validator = Validator::create($post);

 // or use closure 

 $validator = Validator::create($post, function ($v)
 {
    // add rules for input fields
 });

The create method expects first argument to be a incoming data to be validated. The second argument is optional. You may pass closure callback.

Defining Validation Rules

The addRule method use to add new rules for validating user inputs against specified rules. You may define single rule per fields or multiple rules for the fields simply delimited using a "pipe" symbol.


 $validator = Validator::create($post, function ($v)
 {
     $v->addRule('name', 'required|min:3|max:5')
       ->addRule('password', 'required|is_int|valid_date')
       ->addRule('phone', 'phone|is_string')
       ->addRule('email', 'valid_email');
    
     return $v;
 });

The addRule method expects two arguments. The first argument should be the field name and the second argument should be rules, use "pipe" symbol to separate multiple rules.

Validating Fields

After adding rules into Validator instance you may use "run" method to perform Validation. The "run" method will simply return boolean value.

 
 if ( $validator->run() ) {
   
   // Success!! Do something  
 }

Retrieving Validation Errors

If defined validation rules doesn't passes Validator will store all errors as array for each fields. Each error messages will be post fixed by "dot" separator with given field name. By default Validator will create system defined error messages, however can override as needed.

Retrieving All Error Messages

The getErrors method helps to retrieve all error messages as array.


 // Displays all errors as array
 $validator->getErrors(); //  ['name.error' => 'The field name is required', 'phone.error' => '..']

 foreach ($validator->getErrors() as $key => $message) {
    echo $message; 
 }

Retrieving Error Message For A Field

You may use same getErrors method to retrieve any particular error string by simply passing the column name as argument.


 echo $validator->getErrors('name'); 
 echo $validator->getErrors('phone');

Customizing Error Message

Validator also allows you to override system defined error message with custom error message. You may simply use "setCustomError" method for overriding particular message.


 $validator = Validator::create($post, function ($v)
 {
     $v->addRule('name', 'required');
    
     return $v;
 });
 
 $validator->getErrors('name'); // Name is required.

 $validator->setCustomError('name', 'Name field is required and cannot leave empty.');
 $validator->getErrors('name'); // Name field is required and cannot leave empty.

After Validation Hook

The validator also allows to attach callback which will run soon after validation completes. Sometimes you may want to add additional custom validation checks and override error messages or add new one into message array.


 $validator = Validator::create($post, function ($v)
 {
     $v->addRule('name', 'required|min:3|max:5')
       ->addRule('password', 'required|is_int|valid_date')
       ->addRule('phone', 'phone|is_string')
       ->addRule('email', 'valid_email');
    
     return $v;
 });

  
 $validator->after(function($v) 
 {
     if (!$this->checkIfValidationRulePasses()) {

         $v->setCustomError('name', 'Custom Error Message!!');
     }
 });

 if ($validator->run()) {
    // Success!!
 }

Available Validation Rules

Below are list of available rules and methods supports by current version of Validator class, however you can extends and add needed features.

  • required
  • validEmail
  • isIp
  • isInt
  • isString
  • isAlphaNumeric
  • isAlphaNumWithUnderScore
  • min
  • max
  • validUrl
  • phone
  • isEmptyFile

Validation Using Model Class

You may want to organize the code, Validator also helps you such cases. The most organized and convenient approach to validate input data is using Validation Trait to perform validation. You can use "\Cygnite\Database\Cyrus\ValidationTrait" trait either using model class or any other class and define rules. Using model class is recommended.

Using "model:create" command via Cygnite CLI can quickly create a model class for you with sample rules. It also extends ValidationTrait so that simply calling validate method will do all job for you. Let us create a User model using below command.


 php craft model:create user

The above command will generate the user model class for the table "user". Below "Apps\Models\User" class how looks like.


 namespace Apps\Models;

 use Cygnite\Database\Schema;
 use Cygnite\Common\UrlManager\Url;
 use Cygnite\Database\Cyrus\ActiveRecord;
 use Cygnite\Database\Cyrus\ValidationTrait;

 class User extends ActiveRecord
 {
    use ValidationTrait;

    //your database connection name
    protected $database = 'cyrus';

    //protected $tableName = 'user';

    protected $primaryKey = 'id';

    /**
    * Set Validation rules for Form
    *
    * @param $input
    * @return mixed
    */
    public $rules = [
        'name' => 'required|min:5',
        'description' => 'required|min:5',
        'date' => 'required|min:5', 
    ];

    public function __construct()
    {
        parent::__construct();
    }
 }

By default console create command will generate required field validation rules for each fields, however you can modify as your needs.

Validating Fields Using Controller

Now your validator ready to validate fields. You may use validate method in the controller action to perform validation against rules specified. Sample controller class below.


 namespace Apps\Controllers;

 use Cygnite\Mvc\View\View;
 use Cygnite\Common\UrlManager\Url;
 use Cygnite\Foundation\Application;
 use Cygnite\Foundation\Http\Response;
 use Apps\Form\UserForm;
 use Apps\Models\User;
 use Cygnite\Mvc\Controller\AbstractBaseController;

 class UserController extends AbstractBaseController
 {
    protected $layout = 'layouts.base';

    /**
    * Your constructor.
    * @access public
    */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Add a new user
     * @return void
     */
    public function addAction()
    {
       $input = Input::make();

       $user = new User();

       if ($user->validate($input->post())) {
            
          // Success!! Save a new user

       } else {
           // Retrieve all validation errors
          $errors = $user->validationErrors();
       }

        // We can also use same view page for create and update
        $content = View::create('Apps.Views.user.create', [
                    //'form' => $form->render(),
                    'validation_errors' => $errors,
                    'title' => 'Add a new Breed'
        ]);

        return Response::make($content);
    }
 }

For reference you can generate crud via Cygnite CLI, set routes and check how validation works with model class. For more details about creating models please read Console Commands.

By default CRUD generator uses Model based validation, all your rules must be set into model class.

Appending Error Messages Into Form

Sometimes you may wish to append each error messages below the input form fields, Form class also allows you to append all messages to form. You just need to set the Validator instance using "setValidator" method into your form class. That's all Form build intelligent enough to understand and render each error messages below the input fields. Consider same User Controller as below.


 namespace Apps\Controllers;

 use Apps\Models\User;
 use Apps\Form\UserForm;
 use Cygnite\Mvc\View\View;
 use Cygnite\Common\Input\Input;
 use Cygnite\Foundation\Http\Response;
 use Cygnite\Mvc\Controller\AbstractBaseController;

 class UserController extends AbstractBaseController
 {
    protected $layout = 'layouts.base';

    /**
    * Your constructor.
    * @access public
    */
    public function __construct()
    {
        parent::__construct();
    }

     /**
     * Add a new user
     * @return void
     */
    public function addAction()
    {
        $form = new UserForm();
        $form->action = 'add';
        $input = Input::make();

        //Check is form posted
        if ($input->hasPost('btnSubmit') == true) {

            $user = new User(); // Model class

            //Run validation
            if ($user->validate($input->post())) {

                // get post array value except the submit button
                $postArray = $input->except('btnSubmit')->post();

                $user->name = $postArray["name"];
                $user->description = $postArray["description"];
                $user->date = $postArray["date"];

                // Save form details
                if ($user->save()) {
                    $this->setFlash('success', 'User added successfully!')
                        ->redirectTo('breed/index/');
                } else {
                    $this->setFlash('error', 'Error occurred while saving User!')
                        ->redirectTo('breed/index/');
                }

            } else {
                //Set validation error into form builder
                $form->errors = $user->validationErrors();
            }

            $form->validator = $user->getValidator();
        }

        // We can also use same view page for create and update
        $content = View::create('Apps.Views.user.create', [
                    'form' => $form->render(),
                    'validation_errors' => $form->errors,
                    'title' => 'Add A New User'
        ]);

        return Response::make($content);
    }
 }

In the above controller class add action method you can find we have saved validation errors into form as below.


 $form = new UserForm();
 $form->action = 'add';
 $input = Input::make();
 $user = new \Apps\Models\User();

  //Run validation
 if ($user->validate($input->post())) {

 } else {
     //Append Validation Errors In The Form
     $form->errors = $user->validationErrors();
 }

Below methods are exposed by "Cygnite\Database\Cyrus\ValidationTrait" trait.


 use Apps\Models\User;

 $user = new User();
 $user->getValidator(); // Get the validator instance

 $user->validationErrors(); // Get all error messages 

 $user->validate($inputs); // Validate User inputs

 $user->setErrors($errors); // Set Custom error messages

 $user->hasErrors(); // Check if error messages exists

Customize Error Message And Setting Into Form

Typically all forms are stored in the "src/Apps/Form/" directory. You can find some sample form class into the same path for reference. Cygnite's Form builder also allows to customized and append into HTML form. Below example shows how to override default error message.


 namespace Apps\Form;

 use Cygnite\FormBuilder\Form;
 use Cygnite\Foundation\Application;
 use Cygnite\Common\UrlManager\Url;
 
 class UserForm extends Form
 {

    //.........

    public function setValidator($validator)
    {
        $this->validator = $validator;

        return $this;
    }

    /**
     *  Build form and return object
     * @return BreedForm
     */
    public function buildForm()
    {
        $id = (isset($this->model->id)) ? $this->model->id : '';

        // Customize error messages and append into form
        if (is_object($this->validator)) {

            //$this->validator->setCustomError('column.error', 'Your Custom Error Message');
        }

        ................

        
        return $this;
    }
   
    public function render()
    {
        return $this->buildForm()->getForm();
    }  
 }

You are allowed to customize error message only if you set validator instance in your form class. You may find more details about "FormBuilder" class by reading documentation. in That's all about validator.

Follow Us On Facebook Twitter Google+ Linkedin
Released Under The MIT Public License. Copyrights @2012-2017. Powered by- Sanjoy Dey Productions.