mirror of
https://github.com/vlucas/valitron.git
synced 2025-12-30 23:01:52 +00:00
Working basic validations with tests
This commit is contained in:
commit
ef40f0e187
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
composer.phar
|
||||
vendor
|
||||
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@ -0,0 +1,13 @@
|
||||
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
||||
language: php
|
||||
|
||||
# list any PHP version you want to test against
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
|
||||
before_script:
|
||||
- composer install
|
||||
|
||||
# Script to run tests
|
||||
script: phpunit
|
||||
32
LICENSE.txt
Normal file
32
LICENSE.txt
Normal file
@ -0,0 +1,32 @@
|
||||
The BSD 3-Clause License
|
||||
http://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
Copyright (c) 2013, Vance Lucas
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Vance Lucas nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
||||
## Valitron: Easy Validation That Doesn't Suck
|
||||
|
||||
Valitron is a simple, minimal and elegant stand-alone validation library
|
||||
with NO dependencies. Valitron uses simple, straightforward validation
|
||||
methods with a focus on readable and concise syntax. Valitron is the
|
||||
simple and pragmatic validation library you've been loking for.
|
||||
|
||||
[](http://travis-ci.org/vlucas/valitron)
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Make your changes
|
||||
4. Run the tests, adding new ones for your own code if necessary (`phpunit`)
|
||||
5. Commit your changes (`git commit -am 'Added some feature'`)
|
||||
6. Push to the branch (`git push origin my-new-feature`)
|
||||
7. Create new Pull Request
|
||||
|
||||
24
composer.json
Normal file
24
composer.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "vlucas/valitron",
|
||||
"version": "1.0.0",
|
||||
"type": "library",
|
||||
"description": "Simple, elegant, stand-alone validation library with NO dependencies",
|
||||
"keywords": ["validation", "validator", "valid"],
|
||||
"homepage": "http://github.com/vlucas/valitron",
|
||||
"license" : "BSD",
|
||||
"authors" : [
|
||||
{
|
||||
"name": "Vance Lucas",
|
||||
"email": "vance@vancelucas.com",
|
||||
"homepage": "http://www.vancelucas.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Valitron": "src/"
|
||||
}
|
||||
}
|
||||
}
|
||||
18
phpunit.xml
Normal file
18
phpunit.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Valitron Test Suite">
|
||||
<directory suffix=".php">tests/Valitron</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
298
src/Valitron/Validator.php
Normal file
298
src/Valitron/Validator.php
Normal file
@ -0,0 +1,298 @@
|
||||
<?php
|
||||
namespace Valitron;
|
||||
|
||||
/**
|
||||
* Validation Class
|
||||
*
|
||||
* Validates input against certian criteria
|
||||
*
|
||||
* @package Valitron
|
||||
* @author Vance Lucas <vance@vancelucas.com>
|
||||
* @link http://www.vancelucas.com/
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
protected $_fields = array();
|
||||
protected $_errors = array();
|
||||
protected $_validations = array();
|
||||
protected static $_rules = array();
|
||||
|
||||
|
||||
/**
|
||||
* Setup validation
|
||||
*/
|
||||
public function __construct($data, $fields = array())
|
||||
{
|
||||
// Allows filtering of used input fields against optional second array of field names allowed
|
||||
// This is useful for limiting raw $_POST or $_GET data to only known fields
|
||||
foreach($data as $field => $value) {
|
||||
if(empty($fields) || (!empty($fields) && in_array($field, $fields))) {
|
||||
$this->_fields[$field] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register new validation rule callback
|
||||
*/
|
||||
public static function addRule($name, $callback)
|
||||
{
|
||||
if(!is_callable($callback)) {
|
||||
throw new \InvalidArgumentException("Second argument must be a valid callback. Given argument was not callable.");
|
||||
}
|
||||
|
||||
static::$_rules[$name] = $callback;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to add validation rules
|
||||
*/
|
||||
public function rule($rule, $fields, $message = null)
|
||||
{
|
||||
if(!isset(static::$_rules[$rule])) {
|
||||
throw new \InvalidArgumentException("Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule().");
|
||||
}
|
||||
|
||||
$this->_validations[] = array(
|
||||
'rule' => $rule,
|
||||
'fields' => (array) $fields,
|
||||
'message' => $message
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method to add validation rules
|
||||
*/
|
||||
public function __call($rule, array $args)
|
||||
{
|
||||
if(!isset(static::$_rules[$rule])) {
|
||||
throw new \InvalidArgumentException("Method '" . $rule . "' does not exist, or rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule().");
|
||||
}
|
||||
|
||||
array_unshift($args, $rule);
|
||||
call_user_func_array(array($this, 'rule'), $args);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required field validator
|
||||
*/
|
||||
public function validateRequired($field, $value, array $params = array())
|
||||
{
|
||||
if(is_null($value)) {
|
||||
return false;
|
||||
} elseif(is_string($value) and trim($value) === '') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is a valid IP address
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateIp($field, $value)
|
||||
{
|
||||
return filter_var($value, FILTER_VALIDATE_IP) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is a valid e-mail address
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateEmail($field, $value)
|
||||
{
|
||||
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is a valid URL by syntax
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateUrl($field, $value)
|
||||
{
|
||||
return filter_var($value, FILTER_VALIDATE_URL) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is an active URL by verifying DNS record
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateActiveUrl($field, $value)
|
||||
{
|
||||
$url = str_replace(array('http://', 'https://', 'ftp://'), '', strtolower($value));
|
||||
|
||||
return checkdnsrr($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute contains only alphabetic characters
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateAlpha($field, $value)
|
||||
{
|
||||
return preg_match('/^([a-z])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute contains only alpha-numeric characters.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateAlphaNum($field, $value)
|
||||
{
|
||||
return preg_match('/^([a-z0-9])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute contains only alpha-numeric characters, dashes, and underscores.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateAlphaDash($field, $value)
|
||||
{
|
||||
return preg_match('/^([-a-z0-9_-])+$/i', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute passes a regular expression check.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateRegex($field, $value, $params)
|
||||
{
|
||||
return preg_match($params[0], $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute is a valid date.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateDate($field, $value)
|
||||
{
|
||||
return strtotime($value) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an attribute matches a date format.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateDateFormat($field, $value, $params)
|
||||
{
|
||||
$parsed = date_parse_from_format($params[0], $value);
|
||||
|
||||
return $parsed['error_count'] === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the date is before a given date.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateBefore($field, $value, $params)
|
||||
{
|
||||
return strtotime($value) < strtotime($params[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the date is after a given date.
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @return bool
|
||||
*/
|
||||
public static function validateAfter($field, $value, $params)
|
||||
{
|
||||
return strtotime($value) > strtotime($params[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of fields and data
|
||||
*/
|
||||
public function data($field = null)
|
||||
{
|
||||
return $this->_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of error messages
|
||||
*/
|
||||
public function errors($field = null)
|
||||
{
|
||||
if($field !== null) {
|
||||
return isset($this->_errors[$field]) ? $this->_errors[$field] : false;
|
||||
}
|
||||
return $this->_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error to error messages array
|
||||
*/
|
||||
public function error($field, $msg)
|
||||
{
|
||||
// Add to error array
|
||||
$this->_errors[$field][] = sprintf($msg, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run validations and return boolean result
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validate()
|
||||
{
|
||||
foreach($this->_validations as $v) {
|
||||
foreach($v['fields'] as $field) {
|
||||
$value = isset($this->_fields[$field]) ? $this->_fields[$field] : null;
|
||||
$result = call_user_func(static::$_rules[$v['rule']], $field, $value);
|
||||
if(!$result) {
|
||||
$this->error($field, $v['message']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count($this->errors()) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Register default validations here so they can be overridden by user after include
|
||||
$class = __NAMESPACE__ . '\Validator';
|
||||
$class::addRule('required', array($class, 'validateRequired'));
|
||||
$class::addRule('email', array($class, 'validateEmail'));
|
||||
$class::addRule('url', array($class, 'validateUrl'));
|
||||
|
||||
61
tests/Valitron/Validate.php
Normal file
61
tests/Valitron/Validate.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
use Valitron\Validator;
|
||||
|
||||
class ValidateTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testValidWithNoRules()
|
||||
{
|
||||
$v = new Validator(array('name' => 'Chester Tester'));
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testOptionalFieldFilter()
|
||||
{
|
||||
$v = new Validator(array('foo' => 'bar', 'bar' => 'baz'), array('foo'));
|
||||
$this->assertEquals($v->data(), array('foo' => 'bar'));
|
||||
}
|
||||
|
||||
public function testRequired()
|
||||
{
|
||||
$v = new Validator(array('name' => 'Chester Tester'));
|
||||
$v->required('name');
|
||||
$this->assertTrue($v->validate());
|
||||
$this->assertSame(1, count($v->errors('name')));
|
||||
}
|
||||
|
||||
public function testRequiredNonExistentField()
|
||||
{
|
||||
$v = new Validator(array('name' => 'Chester Tester'));
|
||||
$v->required('nonexistent_field');
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testEmailValid()
|
||||
{
|
||||
$v = new Validator(array('name' => 'Chester Tester', 'email' => 'chester@tester.com'));
|
||||
$v->email('email');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testEmailInvalid()
|
||||
{
|
||||
$v = new Validator(array('name' => 'Chester Tester', 'email' => 'chestertesterman'));
|
||||
$v->rule('email', 'email');
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testUrlValid()
|
||||
{
|
||||
$v = new Validator(array('website' => 'http://google.com'));
|
||||
$v->rule('url', 'website');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testUrlInvalid()
|
||||
{
|
||||
$v = new Validator(array('website' => 'shoobedobop'));
|
||||
$v->rule('url', 'website');
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
}
|
||||
|
||||
18
tests/bootstrap.php
Normal file
18
tests/bootstrap.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
error_reporting(-1);
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
/**
|
||||
* Path trickery ensures test suite will always run, standalone or within
|
||||
* another composer package. Designed to find composer autoloader and require
|
||||
*/
|
||||
$vendorPos = strpos(__DIR__, 'vendor/vlucas/valitron');
|
||||
if($vendorPos !== false) {
|
||||
// Package has been cloned within another composer package, resolve path to autoloader
|
||||
$vendorDir = substr(__DIR__, 0, $vendorPos) . 'vendor/';
|
||||
$loader = require $vendorDir . 'autoload.php';
|
||||
} else {
|
||||
// Package itself (cloned standalone)
|
||||
$loader = require __DIR__.'/../vendor/autoload.php';
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user