Viewed   88 times

I need a simple php library which can be used to easily pass rules and field names to, and then validation could be easily performed. There should also be an easy way to retrieve the errors.

Any suggestions?

 Answers

3

I wrote a simple class of my own, combining some regexes i collected over the years with PHP's sanatize and filter functions.

<?
/**
 * Pork Formvalidator. validates fields by regexes and can sanatize them. Uses PHP filter_var built-in functions and extra regexes 
 * @package pork
 */


/**
 * Pork.FormValidator
 * Validates arrays or properties by setting up simple arrays
 * 
 * @package pork
 * @author SchizoDuckie
 * @copyright SchizoDuckie 2009
 * @version 1.0
 * @access public
 */
class FormValidator
{
    public static $regexes = Array(
            'date' => "^[0-9]{4}[-/][0-9]{1,2}[-/][0-9]{1,2}$",
            'amount' => "^[-]?[0-9]+$",
            'number' => "^[-]?[0-9,]+$",
            'alfanum' => "^[0-9a-zA-Z ,.-_\s?!]+$",
            'not_empty' => "[a-z0-9A-Z]+",
            'words' => "^[A-Za-z]+[A-Za-z \s]*$",
            'phone' => "^[0-9]{10,11}$",
            'zipcode' => "^[1-9][0-9]{3}[a-zA-Z]{2}$",
            'plate' => "^([0-9a-zA-Z]{2}[-]){2}[0-9a-zA-Z]{2}$",
            'price' => "^[0-9.,]*(([.,][-])|([.,][0-9]{2}))?$",
            '2digitopt' => "^d+(,d{2})?$",
            '2digitforce' => "^d+,dd$",
            'anything' => "^[dD]{1,}$"
    );
    private $validations, $sanatations, $mandatories, $errors, $corrects, $fields;


    public function __construct($validations=array(), $mandatories = array(), $sanatations = array())
    {
        $this->validations = $validations;
        $this->sanatations = $sanatations;
        $this->mandatories = $mandatories;
        $this->errors = array();
        $this->corrects = array();
    }

    /**
     * Validates an array of items (if needed) and returns true or false
     *
     */
    public function validate($items)
    {
        $this->fields = $items;
        $havefailures = false;
        foreach($items as $key=>$val)
        {
            if((strlen($val) == 0 || array_search($key, $this->validations) === false) && array_search($key, $this->mandatories) === false) 
            {
                $this->corrects[] = $key;
                continue;
            }
            $result = self::validateItem($val, $this->validations[$key]);
            if($result === false) {
                $havefailures = true;
                $this->addError($key, $this->validations[$key]);
            }
            else
            {
                $this->corrects[] = $key;
            }
        }

        return(!$havefailures);
    }

    /**
     *
     *  Adds unvalidated class to thos elements that are not validated. Removes them from classes that are.
     */
    public function getScript() {
        if(!empty($this->errors))
        {
            $errors = array();
            foreach($this->errors as $key=>$val) { $errors[] = "'INPUT[name={$key}]'"; }

            $output = '$$('.implode(',', $errors).').addClass("unvalidated");'; 
            $output .= "alert('there are errors in the form');"; // or your nice validation here
        }
        if(!empty($this->corrects))
        {
            $corrects = array();
            foreach($this->corrects as $key) { $corrects[] = "'INPUT[name={$key}]'"; }
            $output .= '$$('.implode(',', $corrects).').removeClass("unvalidated");';   
        }
        $output = "<script type='text/javascript'>{$output} </script>";
        return($output);
    }


    /**
     *
     * Sanatizes an array of items according to the $this->sanatations
     * sanatations will be standard of type string, but can also be specified.
     * For ease of use, this syntax is accepted:
     * $sanatations = array('fieldname', 'otherfieldname'=>'float');
     */
    public function sanatize($items)
    {
        foreach($items as $key=>$val)
        {
            if(array_search($key, $this->sanatations) === false && !array_key_exists($key, $this->sanatations)) continue;
            $items[$key] = self::sanatizeItem($val, $this->validations[$key]);
        }
        return($items);
    }


    /**
     *
     * Adds an error to the errors array.
     */ 
    private function addError($field, $type='string')
    {
        $this->errors[$field] = $type;
    }

    /**
     *
     * Sanatize a single var according to $type.
     * Allows for static calling to allow simple sanatization
     */
    public static function sanatizeItem($var, $type)
    {
        $flags = NULL;
        switch($type)
        {
            case 'url':
                $filter = FILTER_SANITIZE_URL;
            break;
            case 'int':
                $filter = FILTER_SANITIZE_NUMBER_INT;
            break;
            case 'float':
                $filter = FILTER_SANITIZE_NUMBER_FLOAT;
                $flags = FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_THOUSAND;
            break;
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_SANITIZE_EMAIL;
            break;
            case 'string':
            default:
                $filter = FILTER_SANITIZE_STRING;
                $flags = FILTER_FLAG_NO_ENCODE_QUOTES;
            break;

        }
        $output = filter_var($var, $filter, $flags);        
        return($output);
    }

    /** 
     *
     * Validates a single var according to $type.
     * Allows for static calling to allow simple validation.
     *
     */
    public static function validateItem($var, $type)
    {
        if(array_key_exists($type, self::$regexes))
        {
            $returnval =  filter_var($var, FILTER_VALIDATE_REGEXP, array("options"=> array("regexp"=>'!'.self::$regexes[$type].'!i'))) !== false;
            return($returnval);
        }
        $filter = false;
        switch($type)
        {
            case 'email':
                $var = substr($var, 0, 254);
                $filter = FILTER_VALIDATE_EMAIL;    
            break;
            case 'int':
                $filter = FILTER_VALIDATE_INT;
            break;
            case 'boolean':
                $filter = FILTER_VALIDATE_BOOLEAN;
            break;
            case 'ip':
                $filter = FILTER_VALIDATE_IP;
            break;
            case 'url':
                $filter = FILTER_VALIDATE_URL;
            break;
        }
        return ($filter === false) ? false : filter_var($var, $filter) !== false ? true : false;
    }       



}

Now this requires mootools for some of the javascript you see here, but you can easily change that to your favorite javascript framework. All it does is look up the element, and add the 'unvalidated' CSS class to it.

Usage is as simple as i always ever wanted:

Example:

$validations = array(
    'name' => 'anything',
    'email' => 'email',
    'alias' => 'anything',
    'pwd'=>'anything',
    'gsm' => 'phone',
    'birthdate' => 'date');
$required = array('name', 'email', 'alias', 'pwd');
$sanatize = array('alias');

$validator = new FormValidator($validations, $required, $sanatize);

if($validator->validate($_POST))
{
    $_POST = $validator->sanatize($_POST);
    // now do your saving, $_POST has been sanatized.
    die($validator->getScript()."<script type='text/javascript'>alert('saved changes');</script>");
}
else
{
    die($validator->getScript());
}

To validate just one element:

$validated = new FormValidator()->validate('[email protected].', 'email');

To sanatize just one element:

$sanatized = new FormValidator()->sanatize('<b>blah</b>', 'string');

The coolest thing about this class is that you can send your form with an ajax or iframe target and execute the resulting script. No need to refresh the page or re-send the same form data back to the browser :) Also, if the script needs changing, there's no difficult overdesigned framework to analyze, just change it any way you want :)

Oh yeah, feel free to use this anywhere you want. No licenses

Monday, August 29, 2022
1

I assume you're validating POSTed forms: use Zend_Form and Zend_Filter

Tuesday, December 20, 2022
 
tom_p
 
2

That works in a general case. But not all address line 1's have a number, Some just have a name. eg House Name, Street Name

if your happy with your regex and you just want it to accept a space. Add a space to the regex

$add_check = '/^[a-z0-9- ]+$/i';

But its still not a good way to match addresses. Using a public API which get real data from the royal mail will be the best. Google API (free but rate limited) or a paid for service like Postcode anywhere will be much better for you

Tuesday, September 6, 2022
2

I've used this library for a couple of personal projects. It's pretty good, though I have had to make my own modifications to it a couple of times - nothing major, though, and it's easy enough to do so.

I'm sure you already do this, but also validate all of your information on the server-side, as well. Client-side-only validation is rarely, if ever, a good idea.

Saturday, August 6, 2022
 
dei8cb
 
4

The library now supports annotations, you can validate your fields just by adding them. Here is an example code snippet.

@NotEmpty
@Order(1)
private EditText fieldEditText;

@Checked(message = "You must agree to the terms.")
@Order(2)
private CheckBox iAgreeCheckBox;

@Length(min = 3, message = "Enter atleast 3 characters.")
@Pattern(regex = "[A-Za-z]+", message = "Should contain only alphabets")
@Order(3)
private TextView regexTextView;

@Password
@Order(4)
private EditText passwordEditText;

@ConfirmPassword
@Order(5)
private EditText confirmPasswordEditText;

The order annotation is optional and specifies the order in which the fields should be validated. This is ONLY required if you want the order of the fields to be preserved during validation. There are also other annotations such as @Email, @IpAddress, @Isbn, etc.,

Android Studio / Gradle

compile 'com.mobsandgeeks:android-saripaar:2.0.2'

Check for the latest available version.

Eclipse
You can download the jar from here and add it to your Android libs directory.

Old Answer (Saripaar v1)
I have authored a library for validation. Here is the associated blog and the project. I have sucessfully used it in production applications and it currently satisfies most of the common scenarios that we face in validation forms for Android. There are rules that come out of the box and if you need to write your own, you can do that by writing your own Rule.

Here is a snippet that illustrates the use of the library.

validator.put(nameEditText, Rules.required("Name is required."));
validator.put(nameEditText, Rules.minLength("Name is too short.", 3));
validator.put(emailEditText, Rules.regex("Email id is invalid.", Rules.REGEX_EMAIL, trim));
validator.put(confirmPwdEditText, Rules.eq("Passwords don't match.", pwdEditText);

There are also or and and rules that allow you to perform && and || operations on several rules. There is also a compositeOr and compositeAnd rule that allows you to perform validations between several Views.

If any of those seem to be insufficient, you can always write your own rule by extending the Rule class.

Thursday, December 1, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :