-
Notifications
You must be signed in to change notification settings - Fork 50
Fix loop validation input context is mutable #24
Changes from all commits
8c35a20
de0e3c9
152ee5b
44cd418
aec915e
d743878
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,16 @@ public function setValue($value) | |
return parent::setValue($value); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function resetValue() | ||
{ | ||
$this->value = []; | ||
$this->hasValue = false; | ||
return $this; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
|
@@ -50,6 +60,20 @@ public function getValue() | |
*/ | ||
public function isValid($context = null) | ||
{ | ||
$hasValue = $this->hasValue(); | ||
$required = $this->isRequired(); | ||
$hasFallback = $this->hasFallback(); | ||
|
||
if (! $hasValue && $hasFallback) { | ||
$this->setValue($this->getFallbackValue()); | ||
return true; | ||
} | ||
|
||
if (! $hasValue && $required) { | ||
$this->setErrorMessage('Value is required'); | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks good per our discussion last week on IRC. For those reading:
|
||
|
||
if (!$this->continueIfEmpty() && !$this->allowEmpty()) { | ||
$this->injectNotEmptyValidator(); | ||
} | ||
|
@@ -64,9 +88,9 @@ public function isValid($context = null) | |
} | ||
$result = $validator->isValid($value, $context); | ||
if (!$result) { | ||
if ($this->hasFallback()) { | ||
if ($hasFallback) { | ||
$this->setValue($this->getFallbackValue()); | ||
$result = true; | ||
return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the third part of the fallback value series:
|
||
} | ||
break; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -231,6 +231,8 @@ public function isValid($context = null) | |
*/ | ||
protected function validateInputs(array $inputs, $data = [], $context = null) | ||
{ | ||
$inputContext = $context ?: (array_merge($this->getRawValues(), (array) $data)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May this should use the filtered version instead the raw value There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Considering that the original from two lines above was using the raw values, we should keep it that way for now. We can address again with the next major version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note before the context was always null for optional values. getRawValues already change the behavior if user call setValue before |
||
|
||
$this->validInputs = []; | ||
$this->invalidInputs = []; | ||
$valid = true; | ||
|
@@ -254,51 +256,14 @@ protected function validateInputs(array $inputs, $data = [], $context = null) | |
continue; | ||
} | ||
|
||
$hasFallback = ($input instanceof Input && $input->hasFallback()); | ||
|
||
// If input is optional (not required), and value is not set, then ignore. | ||
if (!array_key_exists($name, $data) | ||
&& !$input->isRequired() | ||
) { | ||
continue; | ||
} | ||
|
||
// If the value is required, not present in the data set, and | ||
// has no fallback, validation fails. | ||
if (!array_key_exists($name, $data) | ||
&& $input->isRequired() | ||
&& !$hasFallback | ||
) { | ||
$input->setErrorMessage('Value is required'); | ||
$this->invalidInputs[$name] = $input; | ||
|
||
if ($input->breakOnFailure()) { | ||
return false; | ||
} | ||
|
||
$valid = false; | ||
continue; | ||
} | ||
|
||
// If the value is required, not present in the data set, and | ||
// has a fallback, validation passes, and we set the input | ||
// value to the fallback. | ||
if (!array_key_exists($name, $data) | ||
&& $input->isRequired() | ||
&& $hasFallback | ||
) { | ||
$input->setValue($input->getFallbackValue()); | ||
continue; | ||
} | ||
|
||
// Make sure we have a value (empty) for validation of context | ||
if (!array_key_exists($name, $data)) { | ||
$data[$name] = null; | ||
} | ||
|
||
// Validate an input | ||
$inputContext = $context ?: $data; | ||
|
||
if (!$input->isValid($inputContext)) { | ||
// Validation failure | ||
$this->invalidInputs[$name] = $input; | ||
|
@@ -545,7 +510,7 @@ protected function populate() | |
$input->clearRawValues(); | ||
} | ||
|
||
if (!isset($this->data[$name])) { | ||
if (!array_key_exists($name, $this->data)) { | ||
// No value; clear value in this input | ||
if ($input instanceof InputFilterInterface) { | ||
$input->setData([]); | ||
|
@@ -557,6 +522,11 @@ protected function populate() | |
continue; | ||
} | ||
|
||
if ($input instanceof Input) { | ||
$input->resetValue(); | ||
continue; | ||
} | ||
|
||
$input->setValue(null); | ||
continue; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this resolve the issue with the NotEmpty messages that have occurred since 2.4? It seems like we should set it in the same format, using the same key, in order to retain the previous behavior?