Skip to content

Commit 50b4587

Browse files
committed
validators now have a common ancestor
1 parent f620fb2 commit 50b4587

File tree

11 files changed

+143
-35
lines changed

11 files changed

+143
-35
lines changed

app/helpers/MetaFormats/RequestParamData.php

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Exceptions\InternalServerException;
66
use App\Exceptions\InvalidArgumentException;
7+
use App\Helpers\MetaFormats\Validators\BaseValidator;
78
use App\Helpers\MetaFormats\Validators\VArray;
89
use App\Helpers\MetaFormats\Validators\VFormat;
910
use App\Helpers\Swagger\AnnotationParameterData;
@@ -18,6 +19,9 @@ class RequestParamData
1819
public string $name;
1920
public string $description;
2021
public bool $required;
22+
/**
23+
* @var BaseValidator[]
24+
*/
2125
public array $validators;
2226
public bool $nullable;
2327

@@ -94,22 +98,14 @@ public function getFormatName(): ?string
9498
return null;
9599
}
96100

97-
private function hasValidators(): bool
98-
{
99-
if (is_array($this->validators)) {
100-
return count($this->validators) > 0;
101-
}
102-
return $this->validators !== null;
103-
}
104-
105101
/**
106102
* Converts the metadata into metadata used for swagger generation.
107103
* @throws \App\Exceptions\InternalServerException Thrown when the parameter metadata is corrupted.
108104
* @return AnnotationParameterData Return metadata used for swagger generation.
109105
*/
110106
public function toAnnotationParameterData()
111107
{
112-
if (!$this->hasValidators()) {
108+
if (count($this->validators) === 0) {
113109
throw new InternalServerException(
114110
"No validator found for parameter {$this->name}, description: {$this->description}."
115111
);
@@ -123,11 +119,8 @@ public function toAnnotationParameterData()
123119
$nestedArraySwaggerType = $this->validators[0]->getElementSwaggerType();
124120
}
125121

126-
// retrieve the example value from the getExampleValue method if present
127-
$exampleValue = null;
128-
if (method_exists(get_class($this->validators[0]), "getExampleValue")) {
129-
$exampleValue = $this->validators[0]->getExampleValue();
130-
}
122+
// get example value from the first validator
123+
$exampleValue = $this->validators[0]->getExampleValue();
131124

132125
// add nested parameter data if this is an object
133126
$format = $this->getFormatName();
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace App\Helpers\MetaFormats\Validators;
4+
5+
/**
6+
* Base class for all validators.
7+
*/
8+
class BaseValidator
9+
{
10+
/**
11+
* @var string One of the valid swagger types (https://swagger.io/docs/specification/v3_0/data-models/data-types/).
12+
*/
13+
public const SWAGGER_TYPE = "invalid";
14+
15+
/**
16+
* @var bool If true, the validateJson method will be used instead of the validateText one for validation.
17+
* Intended to be changed by Attributes containing validators to change their behavior based on the Attribute type.
18+
*/
19+
public bool $useJsonValidation = true;
20+
21+
/**
22+
* @return string Returns a sample expected value to be validated by the validator.
23+
* This value will be used in generated swagger documents.
24+
*/
25+
public function getExampleValue()
26+
{
27+
return "No example provided.";
28+
}
29+
30+
/**
31+
* Validates a value retrieved from unstructured data sources, such as query parameters.
32+
* @param mixed $value The value to be validated.
33+
* @return bool Whether the value passed the test.
34+
*/
35+
public function validateText(mixed $value): bool
36+
{
37+
// return false by default to enforce overriding in derived types
38+
return false;
39+
}
40+
41+
/**
42+
* Validates a value retrieved from json files (usually request bodies).
43+
* @param mixed $value The value to be validated.
44+
* @return bool Whether the value passed the test.
45+
*/
46+
public function validateJson(mixed $value): bool
47+
{
48+
// return false by default to enforce overriding in derived types
49+
return false;
50+
}
51+
52+
/**
53+
* Validates a value with the configured validator method.
54+
* @param mixed $value The value to be validated.
55+
* @return bool Whether the value passed the test.
56+
*/
57+
public function validate(mixed $value): bool
58+
{
59+
if ($this->useJsonValidation) {
60+
return $this->validateJson($value);
61+
}
62+
return $this->validateText($value);
63+
}
64+
}

app/helpers/MetaFormats/Validators/VArray.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* Validates arrays and their nested elements.
77
*/
8-
class VArray
8+
class VArray extends BaseValidator
99
{
1010
public const SWAGGER_TYPE = "array";
1111

@@ -24,7 +24,7 @@ public function __construct(mixed $nestedValidator = null)
2424

2525
public function getExampleValue()
2626
{
27-
if ($this->nestedValidator !== null && method_exists(get_class($this->nestedValidator), "getExampleValue")) {
27+
if ($this->nestedValidator !== null) {
2828
return $this->nestedValidator->getExampleValue();
2929
}
3030

@@ -43,7 +43,12 @@ public function getElementSwaggerType(): mixed
4343
return $this->nestedValidator::SWAGGER_TYPE;
4444
}
4545

46-
public function validate(mixed $value)
46+
public function validateText(mixed $value): bool
47+
{
48+
return $this->validateJson($value);
49+
}
50+
51+
public function validateJson(mixed $value): bool
4752
{
4853
if (!is_array($value)) {
4954
return false;

app/helpers/MetaFormats/Validators/VBool.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@
55
/**
66
* Validates boolean values. Accepts only boolean true and false.
77
*/
8-
class VBool
8+
class VBool extends BaseValidator
99
{
1010
public const SWAGGER_TYPE = "boolean";
1111

12-
public function validate(mixed $value)
12+
public function getExampleValue(): string
13+
{
14+
return "true";
15+
}
16+
17+
public function validateText(mixed $value): bool
18+
{
19+
// additionally allow 0 and 1
20+
return $value === 0 || $value === 1 || $this->validateJson($value);
21+
}
22+
23+
public function validateJson(mixed $value): bool
1324
{
1425
///TODO: remove 'false' once the testUpdateInstance test issue is fixed.
1526
return $value === true || $value === false || $value === 'false';

app/helpers/MetaFormats/Validators/VDouble.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@
55
/**
66
* Validates doubles. Accepts doubles as well as their stringified versions.
77
*/
8-
class VDouble
8+
class VDouble extends BaseValidator
99
{
1010
public const SWAGGER_TYPE = "number";
1111

12-
public function validate(mixed $value)
12+
public function getExampleValue(): string
13+
{
14+
return "0.1";
15+
}
16+
17+
public function validateText(mixed $value): bool
18+
{
19+
return $this->validateJson($value);
20+
}
21+
22+
public function validateJson(mixed $value): bool
1323
{
1424
// check if it is a double
1525
if (is_double($value)) {

app/helpers/MetaFormats/Validators/VEmail.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ public function getExampleValue()
1818
return "name@domain.tld";
1919
}
2020

21-
public function validate(mixed $value): bool
21+
public function validateText(mixed $value): bool
22+
{
23+
return $this->validateJson($value);
24+
}
25+
26+
public function validateJson(mixed $value): bool
2227
{
2328
if (!parent::validate($value)) {
2429
return false;

app/helpers/MetaFormats/Validators/VFormat.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Validates formats. Accepts any format derived of the base MetaFormat.
1111
* Format fields are validated by validators added to the fields.
1212
*/
13-
class VFormat
13+
class VFormat extends BaseValidator
1414
{
1515
public const SWAGGER_TYPE = "object";
1616
public string $format;
@@ -19,13 +19,18 @@ public function __construct(string $format)
1919
{
2020
$this->format = $format;
2121

22-
// throw immediatelly if the format does not exist
22+
// throw immediately if the format does not exist
2323
if (!FormatCache::formatExists($format)) {
2424
throw new InternalServerException("Format $format does not exist.");
2525
}
2626
}
2727

28-
public function validate(mixed $value)
28+
public function validateText(mixed $value): bool
29+
{
30+
return $this->validateJson($value);
31+
}
32+
33+
public function validateJson(mixed $value): bool
2934
{
3035
// fine-grained checking is done in the properties
3136
return $value instanceof MetaFormat;

app/helpers/MetaFormats/Validators/VInt.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@
55
/**
66
* Validates integers. Accepts ints as well as their stringified versions.
77
*/
8-
class VInt
8+
class VInt extends BaseValidator
99
{
1010
public const SWAGGER_TYPE = "integer";
1111

12-
public function getExampleValue(): int|string
12+
public function getExampleValue(): string
1313
{
1414
return "0";
1515
}
1616

17-
public function validate(mixed $value)
17+
public function validateText(mixed $value): bool
18+
{
19+
return $this->validateJson($value);
20+
}
21+
22+
public function validateJson(mixed $value): bool
1823
{
1924
// check if it is an integer (does not handle integer strings)
2025
if (is_int($value)) {

app/helpers/MetaFormats/Validators/VMixed.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@
77
* Placeholder validator used for endpoints with no existing validation rules.
88
* New endpoints should never use this validator, instead use a more restrictive one.
99
*/
10-
class VMixed
10+
class VMixed extends BaseValidator
1111
{
1212
public const SWAGGER_TYPE = "string";
1313

14-
public function getExampleValue()
14+
public function validateText(mixed $value): bool
1515
{
16-
return "value";
16+
return true;
1717
}
1818

19-
public function validate(mixed $value): bool
19+
public function validateJson(mixed $value): bool
2020
{
2121
return true;
2222
}

app/helpers/MetaFormats/Validators/VString.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* Validates strings.
77
*/
8-
class VString
8+
class VString extends BaseValidator
99
{
1010
public const SWAGGER_TYPE = "string";
1111
private int $minLength;
@@ -31,7 +31,12 @@ public function getExampleValue()
3131
return "text";
3232
}
3333

34-
public function validate(mixed $value): bool
34+
public function validateText(mixed $value): bool
35+
{
36+
return $this->validateJson($value);
37+
}
38+
39+
public function validateJson(mixed $value): bool
3540
{
3641
// do not allow other types
3742
if (!is_string($value)) {

0 commit comments

Comments
 (0)