mirror of
https://github.com/vlucas/valitron.git
synced 2025-12-30 23:01:52 +00:00
Validation of nested arrays, closes #8
This commit is contained in:
parent
8b16a8a962
commit
c197b10891
18
README.md
18
README.md
@ -69,6 +69,23 @@ if($v->validate()) {
|
||||
}
|
||||
```
|
||||
|
||||
You may use dot syntax to access members of multi-dimensional arrays,
|
||||
and an asterisk to validate each member of an array:
|
||||
|
||||
```php
|
||||
$v = new Valitron\Validator(array('settings' => array(
|
||||
array('threshold' => 50),
|
||||
array('threshold' => 90)
|
||||
)));
|
||||
$v->rule('max', 'settings.*.threshold', 100);
|
||||
if($v->validate()) {
|
||||
echo "Yay! We're all good!";
|
||||
} else {
|
||||
// Errors
|
||||
print_r($v->errors());
|
||||
}
|
||||
```
|
||||
|
||||
Setting language and language dir globally:
|
||||
|
||||
```php
|
||||
@ -92,6 +109,7 @@ V::lang('ar');
|
||||
* `accepted` - Checkbox or Radio must be accepted (yes, on, 1, true)
|
||||
* `numeric` - Must be numeric
|
||||
* `integer` - Must be integer number
|
||||
* `array` - Must be array
|
||||
* `length` - String must be certain length
|
||||
* `lengthBetween` - String must be between given lengths
|
||||
* `lengthMin` - String must be greater than given length
|
||||
|
||||
@ -186,6 +186,18 @@ class Validator
|
||||
return $this->validateRequired($field, $value) && in_array($value, $acceptable, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a field is an array
|
||||
*
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateArray($field, $value)
|
||||
{
|
||||
return is_array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a field is numeric
|
||||
*
|
||||
@ -772,6 +784,47 @@ class Validator
|
||||
$this->_labels = array();
|
||||
}
|
||||
|
||||
private function get($data, $identifiers) {
|
||||
$identifier = array_shift($identifiers);
|
||||
|
||||
// Glob match
|
||||
if ($identifier === '*')
|
||||
{
|
||||
$values = array();
|
||||
foreach($data as $row)
|
||||
{
|
||||
list($value, $multiple) = $this->get($row, $identifiers);
|
||||
if ($multiple)
|
||||
{
|
||||
$values = array_merge($values, $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
return array($values, true);
|
||||
}
|
||||
|
||||
// Dead end, abort
|
||||
elseif ($identifier === NULL || ! isset($data[$identifier]))
|
||||
{
|
||||
return array(NULL, false);
|
||||
}
|
||||
|
||||
// Match array element
|
||||
elseif (count($identifiers) === 0)
|
||||
{
|
||||
return array($data[$identifier], false);
|
||||
}
|
||||
|
||||
// We need to go deeper
|
||||
else
|
||||
{
|
||||
return $this->get($data[$identifier], $identifiers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run validations and return boolean result
|
||||
*
|
||||
@ -781,10 +834,10 @@ class Validator
|
||||
{
|
||||
foreach ($this->_validations as $v) {
|
||||
foreach ($v['fields'] as $field) {
|
||||
$value = isset($this->_fields[$field]) ? $this->_fields[$field] : null;
|
||||
list($values, $multiple) = $this->get($this->_fields, explode('.', $field));
|
||||
|
||||
// Don't validate if the field is not required and the value is empty
|
||||
if ($v['rule'] !== 'required' && !$this->hasRule('required', $field) && (! isset($value) || $value === '')) {
|
||||
if ($v['rule'] !== 'required' && !$this->hasRule('required', $field) && (! isset($values) || $values === '' || ($multiple && count($values) == 0))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -795,7 +848,16 @@ class Validator
|
||||
$callback = array($this, 'validate' . ucfirst($v['rule']));
|
||||
}
|
||||
|
||||
$result = call_user_func($callback, $field, $value, $v['params']);
|
||||
if (! $multiple)
|
||||
{
|
||||
$values = array($values);
|
||||
}
|
||||
|
||||
$result = true;
|
||||
foreach($values as $value)
|
||||
{
|
||||
$result = $result && call_user_func($callback, $field, $value, $v['params']);
|
||||
}
|
||||
if (!$result) {
|
||||
$this->error($field, $v['message'], $v['params']);
|
||||
}
|
||||
|
||||
@ -273,6 +273,93 @@ class ValidateTest extends BaseTestCase
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testArrayValid()
|
||||
{
|
||||
$v = new Validator(array('colors' => array('yellow')));
|
||||
$v->rule('array', 'colors');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testAssocArrayValid()
|
||||
{
|
||||
$v = new Validator(array('settings' => array('color' => 'yellow')));
|
||||
$v->rule('array', 'settings');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testArrayInvalid()
|
||||
{
|
||||
$v = new Validator(array('colors' => 'yellow'));
|
||||
$v->rule('array', 'colors');
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testArrayAccess()
|
||||
{
|
||||
$v = new Validator(array('settings' => array('enabled' => true)));
|
||||
$v->rule('boolean', 'settings.enabled');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testArrayAccessInvalid()
|
||||
{
|
||||
$v = new Validator(array('settings' => array('threshold' => 500)));
|
||||
$v->rule('max', 'settings.threshold', 100);
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testForeachArrayAccess()
|
||||
{
|
||||
$v = new Validator(array('settings' => array(
|
||||
array('enabled' => true),
|
||||
array('enabled' => true)
|
||||
)));
|
||||
$v->rule('boolean', 'settings.*.enabled');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testForeachArrayAccessInvalid()
|
||||
{
|
||||
$v = new Validator(array('settings' => array(
|
||||
array('threshold' => 50),
|
||||
array('threshold' => 500)
|
||||
)));
|
||||
$v->rule('max', 'settings.*.threshold', 100);
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testNestedForeachArrayAccess()
|
||||
{
|
||||
$v = new Validator(array('widgets' => array(
|
||||
array('settings' => array(
|
||||
array('enabled' => true),
|
||||
array('enabled' => true)
|
||||
)),
|
||||
array('settings' => array(
|
||||
array('enabled' => true),
|
||||
array('enabled' => true)
|
||||
))
|
||||
)));
|
||||
$v->rule('boolean', 'widgets.*.settings.*.enabled');
|
||||
$this->assertTrue($v->validate());
|
||||
}
|
||||
|
||||
public function testNestedForeachArrayAccessInvalid()
|
||||
{
|
||||
$v = new Validator(array('widgets' => array(
|
||||
array('settings' => array(
|
||||
array('threshold' => 50),
|
||||
array('threshold' => 90)
|
||||
)),
|
||||
array('settings' => array(
|
||||
array('threshold' => 40),
|
||||
array('threshold' => 500)
|
||||
))
|
||||
)));
|
||||
$v->rule('max', 'widgets.*.settings.*.threshold', 100);
|
||||
$this->assertFalse($v->validate());
|
||||
}
|
||||
|
||||
public function testInInvalid()
|
||||
{
|
||||
$v = new Validator(array('color' => 'yellow'));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user