Commit 081a3e51 authored by Taylor Otwell's avatar Taylor Otwell

initial commit of validation classes.

parent adb58347
...@@ -46,6 +46,17 @@ class Str { ...@@ -46,6 +46,17 @@ class Str {
return (function_exists('mb_convert_case')) ? mb_convert_case($value, MB_CASE_TITLE, Config::get('application.encoding')) : ucwords(strtolower($value)); return (function_exists('mb_convert_case')) ? mb_convert_case($value, MB_CASE_TITLE, Config::get('application.encoding')) : ucwords(strtolower($value));
} }
/**
* Get the length of a string.
*
* @param string $value
* @return int
*/
public static function length($value)
{
return function_exists('mb_strlen') ? mb_strlen($value, Config::get('application.encoding')) : strlen($value);
}
/** /**
* Generate a random alpha or alpha-numeric string. * Generate a random alpha or alpha-numeric string.
* *
......
<?php namespace System\Validation;
class Error_Collector {
/**
* All of the error messages.
*
* @var array
*/
public $messages;
/**
* Create a new Error Collector instance.
*
* @return void
*/
public function __construct($messages = array())
{
$this->messages = $messages;
}
/**
* Add an error message to the collector.
*
* @param string $attribute
* @param string $message
* @return void
*/
public function add($attribute, $message)
{
$this->messages[$attribute][] = $message;
}
/**
* Get the first error message for an attribute.
*
* @param string $attribute
* @return string
*/
public function first($attribute)
{
return (count($messages = $this->get($attribute)) > 0) ? $messages[0] : '';
}
/**
* Get all of the error messages for an attribute.
*
* If no attribute is specified, all of the error messages will be returned.
*
* @param string $attribute
* @return array
*/
public function get($attribute = null)
{
if (is_null($attribute))
{
$all = array();
foreach ($this->messages as $messages)
{
$all = array_merge($all, $messages);
}
return $all;
}
return (array_key_exists($attribute, $this->messages)) ? $this->messages[$attribute] : array();
}
}
\ No newline at end of file
<?php namespace System\Validation;
abstract class Rule {
/**
* The attributes being validated.
*
* @var array
*/
public $attributes;
/**
* The validation error message.
*
* @var string
*/
public $message;
/**
* Create a new validation Rule instance.
*
* @param array $attributes
* @param Validator $class
* @return void
*/
public function __construct($attributes)
{
$this->attributes = $attributes;
}
/**
* Run the validation rule.
*
* @param array $attributes
* @param Error_Collector $errors
* @return void
*/
public function validate($attributes, $errors)
{
if (is_null($this->message))
{
throw new \Exception("An error message must be specified for every Eloquent validation rule.");
}
foreach ($this->attributes as $attribute)
{
if ( ! $this->check($attribute, $attributes))
{
$errors->add($attribute, $this->prepare_message($attribute));
}
}
}
/**
* Prepare the message to be added to the error collector.
*
* Attribute and size place-holders will replace with their actual values.
*
* @param string $attribute
* @return string
*/
private function prepare_message($attribute)
{
$message = $this->message;
if (strpos($message, ':attribute'))
{
$message = str_replace(':attribute', Lang::line('attributes.'.$attribute)->get(), $message);
}
if ($this instanceof Rules\Size_Of)
{
$message = str_replace(':max', $this->maximum, $message);
$message = str_replace(':min', $this->minimum, $message);
$message = str_replace(':size', $this->length, $message);
}
return $message;
}
/**
* Set the validation error message.
*
* @param string $message
* @return Rule
*/
public function message($message)
{
$this->message = $message;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Input;
use System\Validation\Rule;
class Acceptance_Of extends Rule {
/**
* The value is that is considered accepted.
*
* @var string
*/
public $accepts = '1';
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
return Input::has($attribute) and (string) Input::get($attribute) === $this->accepts;
}
/**
* Set the accepted value.
*
* @param string $value
* @return Acceptance_Of
*/
public function accepts($value)
{
$this->accepts = $value;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Input;
use System\Validation\Rule;
class Confirmation_Of extends Rule {
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
return Input::has($attribute.'_confirmation') and $attributes[$attribute] === Input::get($attribute.'_confirmation');
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rule;
class Exclusion_Of extends Rule {
/**
* The reserved values for the attribute.
*
* @var string
*/
public $reserved;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
return ! in_array($attributes[$attribute], $this->reserved);
}
/**
* Set the reserved values for the attribute
*
* @param array $reserved
* @return Exclusion_Of
*/
public function from($reserved)
{
$this->reserved = $reserved;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rule;
class Format_Of extends Rule {
/**
* The regular expression that will be used to evaluate the attribute.
*
* @var string
*/
public $expression;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
return preg_match($this->expression, $attributes[$attribute]);
}
/**
* Set the regular expression.
*
* @param string $expression
* @return Format_Of
*/
public function with($expression)
{
$this->expression = $expression;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rule;
class Inclusion_Of extends Rule {
/**
* The accepted values for the attribute.
*
* @var string
*/
public $accepted;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
return in_array($attributes[$attribute], $this->accepted);
}
/**
* Set the accepted values for the attribute.
*
* @param array $accepted
* @return Inclusion_Of
*/
public function in($accepted)
{
$this->accepted = $accepted;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rule;
class Presence_Of extends Rule {
/**
* Indicates an empty string should be considered present.
*
* @var bool
*/
public $allow_empty = false;
/**
* Indicates a null should be considered present.
*
* @var bool
*/
public $allow_null = false;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return false;
}
if (is_null($attributes[$attribute]) and ! $this->allow_null)
{
return false;
}
if (trim((string) $attributes[$attribute]) === '' and ! $this->allow_empty)
{
return false;
}
return true;
}
/**
* Allow an empty string to be considered present.
*
* @return Presence_Of
*/
public function allow_empty()
{
$this->allow_empty = true;
return $this;
}
/**
* Allow a null to be considered present.
*
* @return Presence_Of
*/
public function allow_null()
{
$this->allow_null = true;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Str;
use System\Validation\Rule;
class Size_Of extends Rule {
/**
* The exact size the attribute must be.
*
* @var int
*/
public $length;
/**
* The maximum size of the attribute.
*
* @var int
*/
public $maximum;
/**
* The minimum size of the attribute.
*
* @var int
*/
public $minimum;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
if (is_numeric($attributes[$attribute]))
{
return $this->check_number($attribute, $attributes);
}
else
{
return $this->check_string($attribute, $attributes);
}
}
/**
* Evaluate the validity of a numeric attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
private function check_number($attribute, $attributes)
{
if ( ! is_null($this->length) and $attributes[$attribute] !== $this->length)
{
return false;
}
if ( ! is_null($this->maximum) and $attributes[$attribute] > $this->maximum)
{
return false;
}
if ( ! is_null($this->minimum and $attributes[$attribute] < $this->minimum))
{
return false;
}
return true;
}
/**
* Evaluate the validity of a string attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check_string($attribute, $attributes)
{
$value = trim((string) $attributes[$attribute]);
if ( ! is_null($this->length) and Str::length($value) !== $this->length)
{
return false;
}
if ( ! is_null($this->maximum) and Str::length($value) > $this->maximum)
{
return false;
}
if ( ! is_null($this->minimum) and Str::length($value) < $this->minimum)
{
return false;
}
return true;
}
/**
* Set the exact size the attribute must be.
*
* @param int $length
* @return Size_Of
*/
public function is($length)
{
$this->length = $length;
return $this;
}
/**
* Set the minimum and maximize size of the attribute.
*
* @param int $minimum
* @param int $maximum
* @return Size_Of
*/
public function between($minimum, $maximum)
{
$this->minimum = $minimum;
$this->maximum = $maximum;
return $this;
}
/**
* Set the minimum size the attribute.
*
* @param int $minimum
* @return Size_Of
*/
public function at_least($minimum)
{
$this->minimum = $minimum;
return $this;
}
/**
* Set the maximum size the attribute.
*
* @param int $maximum
* @return Size_Of
*/
public function less_than($maximum)
{
$this->maximum = $maximum;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\DB;
use System\DB\Eloquent;
use System\Validation\Rule;
class Uniqueness_Of extends Rule {
/**
* The database table that should be checked.
*
* @var string
*/
public $table;
/**
* The database column that should be checked.
*
* @var string
*/
public $column;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
if (is_null($this->column))
{
$this->column = $attribute;
}
return DB::table(Eloquent::table($this->table)->where($this->column, '=', $attributes[$attribute])->count() == 0;
}
/**
* Set the database table and column.
*
* @param string $table
* @param string $column
* @return Uniqueness_Of
*/
public function on($table, $column = null)
{
$this->table = $table;
$this->column = $column;
return $this;
}
}
\ No newline at end of file
<?php namespace System\Validation\Rules;
use System\Validation\Rule;
class With_Callback extends Rule {
/**
* The callback.
*
* @var function
*/
public $callback;
/**
* Evaluate the validity of an attribute.
*
* @param string $attribute
* @param array $attributes
* @return void
*/
public function check($attribute, $attributes)
{
if ( ! array_key_exists($attribute, $attributes))
{
return true;
}
if ( ! is_callable($this->callback))
{
throw new \Exception("A validation callback for the [$attribute] attribute is not callable.");
}
return call_user_func($this->callback, $attributes[$attribute]);
}
/**
* Set the validation callback.
*
* @param function $callback
* @return With_Callback
*/
public function using($callback)
{
$this->callback = $callback;
return $this;
}
}
\ No newline at end of file
<?php namespace System;
class Validator {
/**
* The attributes being validated.
*
* @var array
*/
public $attributes;
/**
* The validation error collector.
*
* @var Error_Collector
*/
public $errors;
/**
* The validation rules.
*
* @var array
*/
public $rules = array();
/**
* Create a new Eloquent validator instance.
*
* @param mixed $target
* @return void
*/
public function __construct($target)
{
// ---------------------------------------------------------
// If the source is an Eloquent model, use the model's
// attributes as the validation attributes.
// ---------------------------------------------------------
$this->attributes = ($target instanceof DB\Eloquent) ? $target->attributes : (array) $target;
$this->errors = new Validation\Error_Collector;
}
/**
* Create a new Eloquent validator instance.
*
* @param mixed $target
* @return Validator
*/
public static function of($target)
{
return new static($target);
}
/**
* Determine if the model passes all of the validation rules.
*
* @return bool
*/
public function is_valid()
{
$this->errors->messages = array();
foreach ($this->rules as $rule)
{
// ---------------------------------------------------------
// The error collector is passed to the rule so that the
// rule may conveniently add error messages.
// ---------------------------------------------------------
$rule->validate($this->attributes, $this->errors);
}
return count($this->errors->messages) === 0;
}
/**
* Magic Method for dynamically creating validation rules.
*/
public function __call($method, $parameters)
{
// ---------------------------------------------------------
// Check if the validation rule is defined in the rules
// directory. If it is, create a new rule and return it.
// ---------------------------------------------------------
if (file_exists(SYS_PATH.'validation/rules/'.$method.EXT))
{
$rule = '\\System\\Validation\\Rules\\'.$method;
return $this->rules[] = new $rule($parameters);
}
throw new \Exception("Method [$method] does not exist on Validator class.");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment