Implements: ArrayAccess
This class is a transparent base class for Validation and should not be accessed directly.
Array and variable validation.
Class declared in SYSPATH/classes/Kohana/Validation.php on line 12.
$_boundarray(0)
$_dataarray(0)
$_empty_rulesarray(2) ( 0 => string(9) "not_empty" 1 => string(7) "matches" )
$_errorsarray(0)
$_labelsarray(0)
$_rulesarray(0)
Sets the unique "any field" key and creates an ArrayObject from the passed array.
array
$array
required - Array to validate void
public function __construct(array $array)
{
$this->_data = $array;
}
Bind a value to a parameter definition.
// This allows you to use :model in the parameter definition of rules
$validation->bind(':model', $model)
->rule('status', 'valid_status', [':model']);
string
$key
required - Variable name or an array of variables mixed
$value
= NULL - Value $this
public function bind($key, $value = null)
{
if (is_array($key)) {
foreach ($key as $name => $value) {
$this->_bound[$name] = $value;
}
} else {
$this->_bound[$key] = $value;
}
return $this;
}
Executes all validation rules. This should typically be called within an if/else block.
if ($validation->check())
{
// The data is valid, do something here
}
boolean
public function check()
{
if (Kohana::$profiling === true) {
// Start a new benchmark
$benchmark = Profiler::start('Validation', __FUNCTION__);
}
// New data set
$data = $this->_errors = [];
// Store the original data because this class should not modify it post-validation
$original = $this->_data;
// Get a list of the expected fields
$expected = Arr::merge(array_keys($original), array_keys($this->_labels));
// Import the rules locally
$rules = $this->_rules;
foreach ($expected as $field) {
// Use the submitted value or null if no data exists
$data[$field] = Arr::get($this, $field);
if (isset($rules[true])) {
if (!isset($rules[$field])) {
// Initialize the rules for this field
$rules[$field] = [];
}
// Append the rules
$rules[$field] = array_merge($rules[$field], $rules[true]);
}
}
// Overload the current array with the new one
$this->_data = $data;
// Remove the rules that apply to every field
unset($rules[true]);
// Bind the validation object to :validation
$this->bind(':validation', $this);
// Bind the data to :data
$this->bind(':data', $this->_data);
// Execute the rules
foreach ($rules as $field => $set) {
// Get the field value
$value = $this[$field];
// Bind the field name and value to :field and :value respectively
$this->bind([
':field' => $field,
':value' => $value,
]);
foreach ($set as $array) {
// Rules are defined as [$rule, $params]
list($rule, $params) = $array;
foreach ($params as $key => $param) {
if (is_string($param) AND array_key_exists($param, $this->_bound)) {
// Replace with bound value
$params[$key] = $this->_bound[$param];
}
}
// Default the error name to be the rule (except array and lambda rules)
$error_name = $rule;
if (is_array($rule)) {
// Allows rule('field', [':model', 'some_rule']);
if (is_string($rule[0]) AND array_key_exists($rule[0], $this->_bound)) {
// Replace with bound value
$rule[0] = $this->_bound[$rule[0]];
}
// This is an array callback, the method name is the error name
$error_name = $rule[1];
$passed = call_user_func_array($rule, $params);
} elseif (!is_string($rule)) {
// This is a lambda function, there is no error name (errors must be added manually)
$error_name = false;
$passed = call_user_func_array($rule, $params);
} elseif (method_exists('Valid', $rule)) {
// Use a method in this object
$method = new ReflectionMethod('Valid', $rule);
// Call static::$rule($this[$field], $param, ...) with Reflection
$passed = $method->invokeArgs(null, $params);
} elseif (strpos($rule, '::') === false) {
// Use a function call
$function = new ReflectionFunction($rule);
// Call $function($this[$field], $param, ...) with Reflection
$passed = $function->invokeArgs($params);
} else {
// Split the class and method of the rule
list($class, $method) = explode('::', $rule, 2);
// Use a static method call
$method = new ReflectionMethod($class, $method);
// Call $Class::$method($this[$field], $param, ...) with Reflection
$passed = $method->invokeArgs(null, $params);
}
// Ignore return values from rules when the field is empty
if (!in_array($rule, $this->_empty_rules) AND ! Valid::not_empty($value))
continue;
if ($passed === false AND $error_name !== false) {
// Add the rule to the errors
$this->error($field, $error_name, $params);
// This field has an error, stop executing rules
break;
} elseif (isset($this->_errors[$field])) {
// The callback added the error manually, stop checking rules
break;
}
}
}
// Unbind all the automatic bindings to avoid memory leaks.
unset($this->_bound[':validation']);
unset($this->_bound[':data']);
unset($this->_bound[':field']);
unset($this->_bound[':value']);
// Restore the data to its original form
$this->_data = $original;
if (isset($benchmark)) {
// Stop benchmarking
Profiler::stop($benchmark);
}
return empty($this->_errors);
}
Copies the current rules to a new array.
$copy = $array->copy($new_data);
array
$array
required - New data set Validation
public function copy(array $array)
{
// Create a copy of the current validation set
$copy = clone $this;
// Replace the data set
$copy->_data = $array;
return $copy;
}
Returns the array of data to be validated.
array
public function data()
{
return $this->_data;
}
Add an error to a field.
string
$field
required - Field name string
$error
required - Error message array
$params
= NULL - $params $this
public function error($field, $error, array $params = null)
{
$this->_errors[$field] = [$error, $params];
return $this;
}
Returns the error messages. If no file is specified, the error message will be the name of the rule that failed. When a file is specified, the message will be loaded from "field/rule", or if no rule-specific message exists, "field/default" will be used. If neither is set, the returned message will be "file/field/rule".
By default all messages are translated using the default language. A string can be used as the second parameter to specified the language that the message was written in.
// Get errors from messages/forms/login.php
$errors = $Validation->errors('forms/login');
string
$file
= NULL - File to load error messages from mixed
$translate
= bool TRUE - Translate the message array
public function errors($file = null, $translate = true)
{
if ($file === null) {
// Return the error list
return $this->_errors;
}
// Create a new message list
$messages = [];
foreach ($this->_errors as $field => $set) {
list($error, $params) = $set;
// Get the label for this field
$label = $this->_labels[$field];
if ($translate) {
if (is_string($translate)) {
// Translate the label using the specified language
$label = __($label, null, $translate);
} else {
// Translate the label
$label = __($label);
}
}
// Start the translation values list
$values = [
':field' => $label,
':value' => Arr::get($this, $field),
];
if (is_array($values[':value'])) {
// All values must be strings
$values[':value'] = implode(', ', Arr::flatten($values[':value']));
}
if ($params) {
foreach ($params as $key => $value) {
if (is_array($value)) {
// All values must be strings
$value = implode(', ', Arr::flatten($value));
} elseif (is_object($value)) {
// Objects cannot be used in message files
continue;
}
// Check if a label for this parameter exists
if (isset($this->_labels[$value])) {
// Use the label as the value, eg: related field name for "matches"
$value = $this->_labels[$value];
if ($translate) {
if (is_string($translate)) {
// Translate the value using the specified language
$value = __($value, null, $translate);
} else {
// Translate the value
$value = __($value);
}
}
}
// Add each parameter as a numbered value, starting from 1
$values[':param' . ($key + 1)] = $value;
}
}
if ($message = Kohana::message($file, "{$field}.{$error}") AND is_string($message)) {
// Found a message for this field and error
} elseif ($message = Kohana::message($file, "{$field}.default") AND is_string($message)) {
// Found a default message for this field
} elseif ($message = Kohana::message($file, $error) AND is_string($message)) {
// Found a default message for this error
} elseif ($message = Kohana::message('validation', $error) AND is_string($message)) {
// Found a default message for this error
} else {
// No message exists, display the path expected
$message = "{$file}.{$field}.{$error}";
}
if ($translate) {
if (is_string($translate)) {
// Translate the message using specified language
$message = __($message, $values, $translate);
} else {
// Translate the message using the default language
$message = __($message, $values);
}
} else {
// Do not translate, just replace the values
$message = strtr($message, $values);
}
// Set the message for this field
$messages[$field] = $message;
}
return $messages;
}
Creates a new Validation instance.
array
$array
required - Array to use for validation Validation
public static function factory(array $array)
{
return new Validation($array);
}
Sets or overwrites the label name for a field.
string
$field
required - Field name string
$label
required - Label $this
public function label($field, $label)
{
// Set the label for this field
$this->_labels[$field] = $label;
return $this;
}
Sets labels using an array.
array
$labels
required - List of field => label names $this
public function labels(array $labels)
{
$this->_labels = $labels + $this->_labels;
return $this;
}
Checks if key is set in array data. Implements ArrayAccess method.
string
$offset
required - Key to check bool
- Whether the key is setpublic function offsetExists($offset)
{
return isset($this->_data[$offset]);
}
Gets a value from the array data. Implements ArrayAccess method.
string
$offset
required - Key to return mixed
- Value from arraypublic function offsetGet($offset)
{
return $this->_data[$offset];
}
Throws an exception because Validation is read-only. Implements ArrayAccess method.
string
$offset
required - Key to set mixed
$value
required - Value to set void
public function offsetSet($offset, $value)
{
throw new Kohana_Exception('Validation objects are read-only.');
}
Throws an exception because Validation is read-only. Implements ArrayAccess method.
string
$offset
required - Key to unset void
public function offsetUnset($offset)
{
throw new Kohana_Exception('Validation objects are read-only.');
}
Overwrites or appends rules to a field. Each rule will be executed once. All rules must be string names of functions method names. Parameters must match the parameters of the callback function exactly
Aliases you can use in callback parameters: - :validation - the validation object - :field - the field name - :value - the value of the field
// The "username" must not be empty and have a minimum length of 4
$validation->rule('username', 'not_empty')
->rule('username', 'min_length', [':value', 4]);
// The "password" field must match the "password_repeat" field
$validation->rule('password', 'matches', [':validation', 'password', 'password_repeat']);
// Using closure (anonymous function)
$validation->rule('index', function(Validation $array, $field, $value) {
if ($value > 6 AND $value < 10) {
$array->error($field, 'custom');
}
}, [':validation', ':field', ':value']
);
Errors must be added manually when using closures!
string
$field
required - Field name callback
$rule
required - Valid PHP callback or closure array
$params
= NULL - Extra parameters for the rule $this
public function rule($field, $rule, array $params = null)
{
if ($params === null) {
// Default to [':value']
$params = [':value'];
}
if ($field !== true AND ! isset($this->_labels[$field])) {
// Set the field label to the field name
$this->_labels[$field] = $field;
}
// Store the rule and params for this rule
$this->_rules[$field][] = [$rule, $params];
return $this;
}
Add rules using an array.
string
$field
required - Field name array
$rules
required - List of callbacks $this
public function rules($field, array $rules)
{
foreach ($rules as $rule) {
$this->rule($field, $rule[0], Arr::get($rule, 1));
}
return $this;
}