Validation library can now use saved validation groups and custom error groups.

This commit is contained in:
Lonnie Ezell 2016-09-11 23:52:44 -05:00
parent 5adb5ef89f
commit 59a3fe2a1f
No known key found for this signature in database
GPG Key ID: 88F86F2034554774
4 changed files with 148 additions and 6 deletions

View File

@ -40,6 +40,8 @@ return [
// Core Messages
'noRuleSets' => 'No rulesets specified in Validation configuration.',
'ruleNotFound' => '{field} is not a valid rule.',
'groupNotFound' => '%s is not a validation rules group.',
'groupNotArray' => '%s rule group must be an array.',
// Rule Messages
'required' => 'The {field} field is required.',

View File

@ -50,6 +50,11 @@ class Validation implements ValidationInterface
*/
protected $customErrors = [];
/**
* @var \Config\Validation
*/
protected $config;
//--------------------------------------------------------------------
/**
@ -60,6 +65,8 @@ class Validation implements ValidationInterface
public function __construct($config)
{
$this->ruleSetFiles = $config->ruleSets;
$this->config = $config;
}
//--------------------------------------------------------------------
@ -79,6 +86,8 @@ class Validation implements ValidationInterface
$this->loadRuleSets();
$this->loadRuleGroup($group);
// Run through each rule. If we have any field set for
// this rule, then we need to run them through!
foreach ($this->rules as $rField => $ruleString)
@ -118,6 +127,7 @@ class Validation implements ValidationInterface
foreach ($rules as $rule)
{
$callable = is_callable($rule);
$passed = false;
// Rules can contain parameters: max_length[5]
$param = false;
@ -130,7 +140,7 @@ class Validation implements ValidationInterface
// If it's a callable, call and and get out of here.
if ($callable)
{
$value = $param === false
$passed = $param === false
? $rule($value)
: $rule($value, $param, $data);
}
@ -148,7 +158,7 @@ class Validation implements ValidationInterface
$found = true;
$value = $param === false
$passed = $param === false
? $set->$rule($value)
: $set->$rule($value, $param, $data);
break;
@ -163,7 +173,7 @@ class Validation implements ValidationInterface
}
// Set the error message if we didn't survive.
if ($value === false)
if ($passed === false)
{
$this->errors[$field] = $this->getErrorMessage($rule, $field);
@ -299,12 +309,53 @@ class Validation implements ValidationInterface
foreach ($this->ruleSetFiles as $file)
{
$this->ruleSetInstances[] = new $file;
$this->ruleSetInstances[] = new $file();
}
}
//--------------------------------------------------------------------
/**
* Loads custom rule groups (if set) into the current rules.
*
* Rules can be pre-defined in Config\Validation and can
* be any name, but must all still be an array of the
* same format used with setRules(). Additionally, check
* for {group}_errors for an array of custom error messages.
*
* @param string|null $group
*/
protected function loadRuleGroup(string $group = null)
{
if (empty($group))
{
return;
}
if (! isset($this->config->$group))
{
throw new \InvalidArgumentException(sprintf(lang('Validation.groupNotFound'), $group));
}
if (! is_array($this->config->$group))
{
throw new \InvalidArgumentException(sprintf(lang('Validation.groupNotArray'), $group));
}
$this->rules = $this->config->$group;
// If {group}_errors exists in the config file,
// then override our custom errors with them.
$errorName = $group.'_errors';
if (isset($this->config->$errorName))
{
$this->customErrors = $this->config->$errorName;
}
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Errors

View File

@ -12,7 +12,15 @@ class ValidationTest extends \CIUnitTestCase
protected $config = [
'ruleSets' => [
\CodeIgniter\Validation\Rules::class,
]
],
'groupA' => [
'foo' => 'required|min_length[5]'
],
'groupA_errors' => [
'foo' => [
'min_length' => 'Shame, shame. Too short.'
]
]
];
//--------------------------------------------------------------------
@ -149,6 +157,32 @@ class ValidationTest extends \CIUnitTestCase
//--------------------------------------------------------------------
public function testGroupsReadFromConfig()
{
$data = [
'foo' => 'bar'
];
$this->assertFalse($this->validation->run($data, 'groupA'));
$this->assertEquals('Shame, shame. Too short.', $this->validation->getError('foo'));
}
//--------------------------------------------------------------------
/**
* @group single
*/
public function testGroupsReadFromConfigValid()
{
$data = [
'foo' => 'barsteps'
];
$this->assertTrue($this->validation->run($data, 'groupA'));
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Rules Tests
//--------------------------------------------------------------------
@ -1224,7 +1258,6 @@ class ValidationTest extends \CIUnitTestCase
/**
* @dataProvider requiredWithoutProvider
* @group single
*
* @param $check
* @param $expected

View File

@ -63,6 +63,62 @@ data to be validated::
$validation->withRequest($this->request)
->run();
**************************************************
Saving Sets of Validation Rules to the Config File
**************************************************
A nice feature of the Validation class is that it permits you to store all
your validation rules for your entire application in a config file. You organize
the rules into "groups". You can specify a different group every time you run
the validation.
How to save your rules
======================
To store your validation rules, simply create a new public property in the ``Config\Validation``
class with the name of your group. This element will hold an array with your validation
rules. As shown earlier, the validation array will have this prototype::
class Validation
{
public $signup = [
'username' => 'required',
'password' => 'required',
'pass_confirm' => 'required|matches[password]',
'email' => 'required|valid_email'
];
}
You can specify the group to use when you call the ``run()`` method::
$validation->run($data, $signup);
You can also store custom error messages in this configuration file by naming the
property the same as the group, and appended with ``_errors``. These will automatically
be used for any errors when this group is used::
class Validation
{
public $signup = [
'username' => 'required',
'password' => 'required',
'pass_confirm' => 'required|matches[password]',
'email' => 'required|valid_email'
];
public $signup_errors = [
'username' => [
'required' => 'You must choose a username.',
],
'email' => [
'valid_email' => 'Please check the Email field. It does not appear to be valid.'
]
]
}
See below for details on the formatting of the array.
*******************
Working With Errors
*******************