Skip to content

Array validation with non iterative rules #753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion src/Illuminate/Validation/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ class Factory {
*/
protected $implicitExtensions = array();

/**
* List of new non iterable rules.
*
* @var array
*/
protected $nonIterative = array();

/**
* The Validator resolver instance.
*
Expand Down Expand Up @@ -78,6 +85,11 @@ public function make(array $data, array $rules, array $messages = array())
// array of data that is given to a validator instances via instantiation.
$implicit = $this->implicitExtensions;

if ( ! empty($this->nonIterative))
{
$validator->addNonIterative($this->nonIterative);
}

$validator->addImplicitExtensions($implicit);

return $validator;
Expand Down Expand Up @@ -127,6 +139,49 @@ public function extendImplicit($rule, Closure $extension)
$this->implicitExtensions[$rule] = $extension;
}

/**
* Register non iterative rules.
*
* @param string/array $rules
* @return void
*/
public function setNonIterative($rules)
{
$this->nonIterative = (array) $rules;
}

/**
* Register additional non iterative rules.
*
* @param string/array $rules
* @return void
*/
public function addNonIterative($rules)
{
$this->nonIterative = array_merge($this->nonIterative, (array) $rules);
}

/**
* Remove non iterative rule.
*
* @param string/array $rules
* @return void
*/
public function removeNonIterative($rules)
{
$this->nonIterative = array_diff($this->nonIterative, (array) $rules);
}

/**
* Get non iterative rules.
*
* @return array
*/
public function getNonIterative()
{
return $this->nonIterative;
}

/**
* Set the Validator instance resolver.
*
Expand Down Expand Up @@ -169,4 +224,4 @@ public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier)
$this->presenceVerifier = $presenceVerifier;
}

}
}
106 changes: 97 additions & 9 deletions src/Illuminate/Validation/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class Validator implements MessageProviderInterface {
*/
protected $extensions = array();

/**
* List of non iterable rules.
*
* @var array
*/
protected $nonIterative = array('Exists', 'Same', 'Different');

/**
* The size related validation rules.
*
Expand Down Expand Up @@ -200,14 +207,37 @@ protected function validate($attribute, $rule)
// that the attribute is required, rules are not run for missing values.
$value = $this->getValue($attribute);

$validatable = $this->isValidatable($rule, $attribute, $value);

$method = "validate{$rule}";

if ($validatable and ! $this->$method($attribute, $value, $parameters, $this))
if (is_array($value) and $this->isIterative($rule))
{
$this->addError($attribute, $rule, $parameters);

// Required, otherwise none of the validation rules will be applied
$value = empty($value) ? array(null) : $value;

foreach ($value as $item)
{

$validatable = $this->isValidatable($rule, $attribute, $item);

if ($validatable and ! $this->$method($attribute, $item, $parameters, $this))
{
$this->addError($attribute, $rule, $parameters);
}

}

} else {

$validatable = $this->isValidatable($rule, $attribute, $value);

if ($validatable and ! $this->$method($attribute, $value, $parameters, $this))
{
$this->addError($attribute, $rule, $parameters);
}

}

}

/**
Expand Down Expand Up @@ -252,6 +282,17 @@ protected function isImplicit($rule)
return in_array($rule, $this->implicitRules);
}

/**
* Determine if a given rule is iterative.
*
* @param string $rule
* @return bool
*/
protected function isIterative($rule)
{
return ! in_array($rule, $this->nonIterative);
}

/**
* Add an error message to the validator's collection of messages.
*
Expand Down Expand Up @@ -286,6 +327,10 @@ protected function validateRequired($attribute, $value)
{
return false;
}
elseif (is_array($value) and empty($value))
{
return false;
}
elseif ($value instanceof File)
{
return (string) $value->getPath() != '';
Expand Down Expand Up @@ -348,9 +393,9 @@ protected function getPresentCount($attributes)
{
$count = 0;

foreach ($attributes as $key)
foreach ($attributes as $attribute)
{
if (isset($this->data[$key]) or isset($this->files[$key]))
if ( ! is_null($this->getValue($attribute)))
{
$count++;
}
Expand Down Expand Up @@ -383,7 +428,7 @@ protected function validateSame($attribute, $value, $parameters)
{
$other = $parameters[0];

return isset($this->data[$other]) and $value == $this->data[$other];
return ! is_null($otherValue = $this->getValue($other)) and $value == $otherValue;
}

/**
Expand All @@ -398,7 +443,7 @@ protected function validateDifferent($attribute, $value, $parameters)
{
$other = $parameters[0];

return isset($this->data[$other]) and $value != $this->data[$other];
return ! is_null($otherValue = $this->getValue($other)) and $value != $otherValue;
}

/**
Expand Down Expand Up @@ -540,7 +585,7 @@ protected function getSize($attribute, $value)
// entire length of the string will be considered the attribute size.
if (is_numeric($value) and $hasNumeric)
{
return $this->data[$attribute];
return $value;
}
elseif ($value instanceof File)
{
Expand Down Expand Up @@ -1390,6 +1435,49 @@ public function addImplicitExtension($rule, Closure $extension)
$this->implicitRules[] = studly_case($rule);
}

/**
* Register non iterative rules.
*
* @param string/array $rules
* @return void
*/
public function setNonIterative($rules)
{
$this->nonIterative = array_map('studly_case', (array) $rules);
}

/**
* Register additional non iterative rules.
*
* @param sring/array $rules
* @return void
*/
public function addNonIterative($rules)
{
$this->nonIterative = array_merge($this->nonIterative, array_map('studly_case', (array) $rules));
}

/**
* Remove non iterative rule.
*
* @param string/array $rules
* @return void
*/
public function removeNonIterative($rules)
{
$this->nonIterative = array_diff($this->nonIterative, (array) $rules);
}

/**
* Get non iterative rules.
*
* @return array
*/
public function getNonIterative()
{
return $this->nonIterative;
}

/**
* Get the data under validation.
*
Expand Down