Skip to content

Commit 83ca351

Browse files
committed
Track if a transformation failed. If a transformation fails don't execute subsequent filter as they'd fail with an invalid type adding another for the current given value irrelevant error
1 parent 5f6ed75 commit 83ca351

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

src/Model/Validator/FilterValidator.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
*/
2222
class FilterValidator extends PropertyTemplateValidator
2323
{
24+
/** @var FilterInterface $filter */
25+
protected $filter;
26+
2427
/**
2528
* FilterValidator constructor.
2629
*
@@ -31,6 +34,7 @@ class FilterValidator extends PropertyTemplateValidator
3134
* @param TransformingFilterInterface|null $transformingFilter
3235
*
3336
* @throws SchemaException
37+
* @throws ReflectionException
3438
*/
3539
public function __construct(
3640
GeneratorConfiguration $generatorConfiguration,
@@ -39,6 +43,8 @@ public function __construct(
3943
array $filterOptions = [],
4044
?TransformingFilterInterface $transformingFilter = null
4145
) {
46+
$this->filter = $filter;
47+
4248
$transformingFilter === null
4349
? $this->validateFilterCompatibilityWithBaseType($filter, $property)
4450
: $this->validateFilterCompatibilityWithTransformedType($filter, $transformingFilter, $property);
@@ -51,7 +57,8 @@ public function __construct(
5157
),
5258
DIRECTORY_SEPARATOR . 'Validator' . DIRECTORY_SEPARATOR . 'Filter.phptpl',
5359
[
54-
'skipTransformedValuesCheck' => false,
60+
'skipTransformedValuesCheck' => $transformingFilter !== null ? '!$transformationFailed' : '',
61+
'isTransformingFilter' => $filter instanceof TransformingFilterInterface,
5562
// check if the given value has a type matched by the filter
5663
'typeCheck' => !empty($filter->getAcceptedTypes())
5764
? '($value !== null && (' .
@@ -73,6 +80,19 @@ public function __construct(
7380
);
7481
}
7582

83+
/**
84+
* Track if a transformation failed. If a transformation fails don't execute subsequent filter as they'd fail with
85+
* an invalid type
86+
*
87+
* @return string
88+
*/
89+
public function getValidatorSetUp(): string
90+
{
91+
return $this->filter instanceof TransformingFilterInterface
92+
? '$transformationFailed = false;'
93+
: '';
94+
}
95+
7696
/**
7797
* Make sure the filter is only executed if a non-transformed value is provided.
7898
* This is required as a setter (eg. for a string property which is modified by the DateTime filter into a DateTime

src/Templates/Validator/Filter.phptpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
{% if skipTransformedValuesCheck %}{{ skipTransformedValuesCheck }} && {% endif %}
22
(
33
{% if typeCheck %}{{ typeCheck }} || {% endif %}
4-
(function (&$value) {
4+
(function (&$value) use (&$transformationFailed): bool {
55
// make sure exceptions from the filter are caught and added to the error handling
66
try {
77
$value = call_user_func_array([\{{ filterClass }}::class, "{{ filterMethod }}"], [$value, {{ filterOptions }}]);
88
} catch (\Exception $e) {
9+
{% if isTransformingFilter %}
10+
$transformationFailed = true;
11+
{% endif %}
12+
913
{{ viewHelper.validationError(transferExceptionMessage) }}
1014
}
1115

tests/Basic/FilterTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,29 @@ public function testFilterChainWithTransformingFilterOnMultiTypeProperty(bool $i
679679
$this->assertSame(['filteredProperty' => '2020-12-12T00:00:00+0000'], $object->toArray());
680680
}
681681

682+
public function testFilterAfterTransformingFilterIsSkippedIfTransformingFilterFails(): void
683+
{
684+
$this->expectException(ErrorRegistryException::class);
685+
$this->expectExceptionMessage(
686+
'Invalid value for property filteredProperty denied by filter dateTime: Invalid Date Time value "Hello"'
687+
);
688+
689+
$className = $this->generateClassFromFile(
690+
'FilterChainMultiType.json',
691+
(new GeneratorConfiguration())
692+
->addFilter(
693+
$this->getCustomFilter(
694+
[self::class, 'exceptionFilter'],
695+
'stripTime',
696+
[DateTime::class]
697+
)
698+
),
699+
false
700+
);
701+
702+
new $className(['filteredProperty' => 'Hello']);
703+
}
704+
682705
public function testFilterWhichAppliesToMultiTypePropertyPartiallyThrowsAnException(): void
683706
{
684707
$this->expectException(SchemaException::class);

0 commit comments

Comments
 (0)