mirror of
https://codeberg.org/reflect/reflect-rules-plugin.git
synced 2025-09-14 08:53:42 +02:00
feat: use CSV for Type::ARRAY in GET Rules (#10)
* fix: eval method for Type::ARRAY and Type::OBJECT * fix: use CSV for GET array * feat(doc): add CSV ref. to README
This commit is contained in:
parent
3e380c0957
commit
5ea11cadf1
2 changed files with 61 additions and 7 deletions
19
README.md
19
README.md
|
@ -141,11 +141,11 @@ Type|Description
|
||||||
--|--
|
--|--
|
||||||
`Type::NUMERIC`|Value must be a number or a numeric string
|
`Type::NUMERIC`|Value must be a number or a numeric string
|
||||||
`Type::STRING`|Value must be a string
|
`Type::STRING`|Value must be a string
|
||||||
`Type::BOOLEAN`|Value must be a boolean or ([**considered bool for GET rules**](#boolean-coercion-from-string-for-search-parameters))
|
`Type::BOOLEAN`|Value must be a boolean ([**considered bool for GET rules**](#boolean-coercion-from-string-for-search-parameters))
|
||||||
`Type::ARRAY`|Value must be a JSON array
|
`Type::ARRAY`|Value must be a JSON array or ([**CSV for GET rules**](#csv-for-search-parameters))
|
||||||
`Type::OBJECT`|Value must be a JSON object
|
`Type::OBJECT`|Value must be a JSON object
|
||||||
`Type::ENUM`|Value must be exactly one of pre-defined values ([**more information**](#typeenum))
|
`Type::ENUM`|Value must be exactly one of pre-defined values ([**more information**](#typeenum))
|
||||||
`Type::NULL`|Value must be null or ([**considered null for GET rules**](#null-coercion-from-string-for-search-parameters))
|
`Type::NULL`|Value must be null ([**considered null for GET rules**](#null-coercion-from-string-for-search-parameters))
|
||||||
|
|
||||||
Will set a `Error::INVALID_PROPERTY_TYPE` error on the current scope and property if failed, except Type::ENUM that will set a `Error::INVALID_PROPERTY_VALUE` with an array of the valid vaules.
|
Will set a `Error::INVALID_PROPERTY_TYPE` error on the current scope and property if failed, except Type::ENUM that will set a `Error::INVALID_PROPERTY_VALUE` with an array of the valid vaules.
|
||||||
|
|
||||||
|
@ -182,6 +182,19 @@ Any other value will cause the `type()` rule to fail.
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> This coercion is only applies for `Ruleset->GET()`. `Ruleset->POST()` will enforce real `true` and `type` values since it's JSON
|
> This coercion is only applies for `Ruleset->GET()`. `Ruleset->POST()` will enforce real `true` and `type` values since it's JSON
|
||||||
|
|
||||||
|
#### CSV array for search parameters
|
||||||
|
A CSV string is expected when `Type::ARRAY` is set for a GET rule.
|
||||||
|
|
||||||
|
*Example:*
|
||||||
|
```
|
||||||
|
https://example.com?typeArray=key1,key2,key3
|
||||||
|
```
|
||||||
|
|
||||||
|
Any other value will cause the `type()` rule to fail.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> This coercion is only applies for `Ruleset->GET()`. `Ruleset->POST()` will enforce a JSON array
|
||||||
|
|
||||||
#### Null coercion from string for search parameters
|
#### Null coercion from string for search parameters
|
||||||
Search parameters are read as strings, a null value is therefor coerced from an empty string `""`.
|
Search parameters are read as strings, a null value is therefor coerced from an empty string `""`.
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
class Rules {
|
class Rules {
|
||||||
|
private const CSV_DELIMITER = ",";
|
||||||
|
|
||||||
private string $property;
|
private string $property;
|
||||||
|
|
||||||
|
/*
|
||||||
|
# Rule properties
|
||||||
|
These properties store rules for an instance of a property
|
||||||
|
*/
|
||||||
|
|
||||||
public bool $required = false;
|
public bool $required = false;
|
||||||
|
|
||||||
// Matched Type against $types array
|
// Matched Type against $types array
|
||||||
|
@ -133,6 +140,40 @@
|
||||||
return !is_bool($value) && in_array($value, $this->enum);
|
return !is_bool($value) && in_array($value, $this->enum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function eval_object(mixed $value, Scope $scope): bool {
|
||||||
|
// Arrays in POST parameters should already be decoded
|
||||||
|
if ($scope === Scope::POST) {
|
||||||
|
return is_array($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode stringified JSON
|
||||||
|
$json = json_decode($value);
|
||||||
|
|
||||||
|
// Failed to decode JSON
|
||||||
|
if ($json === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutate property on superglobal with decoded JSON
|
||||||
|
$GLOBALS[Scope::GET->value][$this->property] = $json;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function eval_array(string $value, Scope $scope): bool {
|
||||||
|
// Arrays in POST parameters should already be decoded
|
||||||
|
if ($scope === Scope::POST) {
|
||||||
|
return is_array($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutate property on superglobal with decoded CSV if not already an array
|
||||||
|
if (!is_array($_GET[$this->property])) {
|
||||||
|
$GLOBALS[Scope::GET->value][$this->property] = explode(self::CSV_DELIMITER, $_GET[$this->property]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
## Public eval methods
|
## Public eval methods
|
||||||
These are the entry-point eval methods that in turn can call other
|
These are the entry-point eval methods that in turn can call other
|
||||||
|
@ -162,8 +203,8 @@
|
||||||
Type::NUMBER => $match = is_numeric($value),
|
Type::NUMBER => $match = is_numeric($value),
|
||||||
Type::STRING => $match = is_string($value),
|
Type::STRING => $match = is_string($value),
|
||||||
Type::BOOLEAN => $match = $this->eval_type_boolean($value, $scope),
|
Type::BOOLEAN => $match = $this->eval_type_boolean($value, $scope),
|
||||||
Type::ARRAY,
|
Type::ARRAY => $match = $this->eval_array($value, $scope),
|
||||||
Type::OBJECT => $match = is_array($value),
|
Type::OBJECT => $match = $this->eval_object($value, $scope),
|
||||||
Type::ENUM => $match = $this->eval_type_enum($value),
|
Type::ENUM => $match = $this->eval_type_enum($value),
|
||||||
Type::NULL => $match = is_null($value)
|
Type::NULL => $match = is_null($value)
|
||||||
};
|
};
|
||||||
|
@ -185,7 +226,7 @@
|
||||||
Type::NUMBER => $this->eval_type($value, $scope) && $value >= $this->min,
|
Type::NUMBER => $this->eval_type($value, $scope) && $value >= $this->min,
|
||||||
Type::STRING => $this->eval_type($value, $scope) && strlen($value) >= $this->min,
|
Type::STRING => $this->eval_type($value, $scope) && strlen($value) >= $this->min,
|
||||||
Type::ARRAY,
|
Type::ARRAY,
|
||||||
Type::OBJECT => $this->eval_type($value, $scope) && count($value) >= $this->min,
|
Type::OBJECT => $this->eval_type($value, $scope) && count($GLOBALS[$scope->value][$this->property]) >= $this->min,
|
||||||
default => true
|
default => true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -195,7 +236,7 @@
|
||||||
Type::NUMBER => $this->eval_type($value, $scope) && $value <= $this->max,
|
Type::NUMBER => $this->eval_type($value, $scope) && $value <= $this->max,
|
||||||
Type::STRING => $this->eval_type($value, $scope) && strlen($value) <= $this->max,
|
Type::STRING => $this->eval_type($value, $scope) && strlen($value) <= $this->max,
|
||||||
Type::ARRAY,
|
Type::ARRAY,
|
||||||
Type::OBJECT => $this->eval_type($value, $scope) && count($value) <= $this->max,
|
Type::OBJECT => $this->eval_type($value, $scope) && count($GLOBALS[$scope->value][$this->property]) <= $this->max,
|
||||||
default => true
|
default => true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue