skey - web developer

Laravel validator for CSS selectors

by on

Last week I was building a backend tool in Laravel, where you could create layout in bootstrap 3 and add CSS selectors like id or class to any container. You wanted to be able to enter more than one class name into input field. Let's say that you want to add 2 classes: col-xs-6 infoBox_4. Laravel hasn't validator for this type of string so I decided to make one. I needed to have validator which accepts alphabetic characters, numbers, underscore symbols, hyphens and spaces. I didn't want to make it over complex, but still wanted to validate that users enters valid css selectors.

Creating rule

We need to create and register the new validation rule with the Validator facade. I went to regulex, my favourite regular expressions visualiser and created the regular expression pattern.

Regular expression for alphabetic characters, numbers, underscore, hyphens and space

Extending validator

Now that we have pattern, we will extend validator. We want to have this rule available everywhere throughout the project, so we will put it to some global space app/start/global.php.


    // app/start/global.php 

    ...

    Validator::extend('css_selectors', function ($attribute, $value) {
        return preg_match('/^[A-Za-z0-9-_\s]+$/', $value);
    });

The custom validator closure receives in this case two arguments: the name of attribute being validated and the value of the attribute. If you don't like closures, you may pass a class and method Validator::extend('css_selectors', 'ValidatorController@validateCssSelectors');.

The validator extension is very simple, if the return value is true, then the rule is ok. If the return value is false, then the rule failed. We also want to show some error message. Lets add it somewhere to lang file for validator.


    // app/lang/en/validation.php

    return array(
    ...
    "css_selectors"   => "The :attribute may only contain letters, numbers, spaces, underscores and hyphens ",
    ...
    );

The new rule is now registered globally and ready to use.

If you decide to create more validation rules later, it is better to separate them from app/start/global.php file into other one. I would suggest to create app/validators.php and put all validator extensions in this new file. Then we will add only one line into global.php require app_path().'/validators.php';

Using the new rule



        $rules = array(
            ...,
            'idName'        => 'required|css_selectors',
            'className'     => 'required|css_selectors'
        );

Conclusion

We learned how to create simple regexp pattern and how to extend Validator with a new Laravel validation rule. I also showed you how to call class with method instead of closure for more complex validators. If you have defined many own validators, then separate them into new file to preserve SRP. The above paths are made in Laravel 4.2, but as I know, no changes were made to Validator in Laravel 5.1 and the only changes are in slightly different locations of files.