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.
$_boundlink to thisarray(0)
$_datalink to thisarray(0)
$_empty_ruleslink to thisarray(2) ( 0 => string(9) "not_empty" 1 => string(7) "matches" )
$_errorslink to thisarray(0)
$_labelslink to thisarray(0)
$_ruleslink to thisarray(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 set
public
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 array
public
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
;
}