mirror of
https://codeberg.org/reflect/reflect-rules-plugin.git
synced 2025-09-13 16:33:42 +02:00
feat: add strict mode (#11)
* feat: add strict mode * feat(doc): add strict mode to README
This commit is contained in:
parent
81a2b2129c
commit
9c837fd194
2 changed files with 80 additions and 11 deletions
10
README.md
10
README.md
|
@ -106,10 +106,20 @@ Error
|
|||
--|
|
||||
[`Error::VALUE_MIN_ERROR`](#min)
|
||||
[`Error::VALUE_MAX_ERROR`](#max)
|
||||
[`Error::UNKNOWN_PROPERTY_NAME`](#strict-mode)
|
||||
[`Error::INVALID_PROPERTY_TYPE`](#type)
|
||||
[`Error::INVALID_PROPERTY_VALUE`](#typeenum)
|
||||
[`Error::MISSING_REQUIRED_PROPERTY`](#required)
|
||||
|
||||
# Strict mode
|
||||
Enable strict mode by initializing a Ruleset with the "strict" argument set to `true`.
|
||||
|
||||
```php
|
||||
new Ruleset(strict: true);
|
||||
```
|
||||
|
||||
Strict mode will not allow undefined properties to be set in all configured scopes. If a property exists in `Scope` that hasn't been defined with a `Rules()` instance, a `Errors::UNKNOWN_PROPERTY_NAME` error will be set.
|
||||
|
||||
# Available rules
|
||||
The following methods can be chained onto a `Rules` instance to enforce certain constraints on a particular property
|
||||
|
||||
|
|
|
@ -10,29 +10,44 @@
|
|||
enum Scope: string {
|
||||
case GET = "_GET";
|
||||
case POST = "_POST";
|
||||
|
||||
static function get_array(): array {
|
||||
return [
|
||||
Scope::GET->name => [],
|
||||
Scope::POST->name => []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
enum Error {
|
||||
case VALUE_MIN_ERROR;
|
||||
case VALUE_MAX_ERROR;
|
||||
case UNKNOWN_PROPERTY_NAME;
|
||||
case INVALID_PROPERTY_TYPE;
|
||||
case INVALID_PROPERTY_VALUE;
|
||||
case MISSING_REQUIRED_PROPERTY;
|
||||
}
|
||||
|
||||
class Ruleset {
|
||||
// Array of arrays with failed constraints
|
||||
private array $errors = [];
|
||||
private bool $is_valid = true;
|
||||
private ?bool $strict;
|
||||
private array $errors;
|
||||
|
||||
public function __construct() {}
|
||||
private array $rules_names;
|
||||
|
||||
public function __construct(bool $strict = false) {
|
||||
/*
|
||||
Strict mode can only be enabled or disabled as a bool argument.
|
||||
'null' is used internally on this property as a re-evaluate flag.
|
||||
*/
|
||||
$this->strict = $strict;
|
||||
|
||||
$this->errors = Scope::get_array();
|
||||
$this->rules_names = Scope::get_array();
|
||||
}
|
||||
|
||||
// Append an error to the array of errors
|
||||
private function add_error(Error $error, Scope $scope, string $property, mixed $expected): void {
|
||||
// Create sub array if this is the first error in this scope
|
||||
if (!array_key_exists($scope->name, $this->errors)) {
|
||||
$this->errors[$scope->name] = [];
|
||||
}
|
||||
|
||||
// Create sub array if this is the first error for this property
|
||||
if (!array_key_exists($property, $this->errors[$scope->name])) {
|
||||
$this->errors[$scope->name][$property] = [];
|
||||
|
@ -40,6 +55,21 @@
|
|||
|
||||
// Set expected value value for property in scope
|
||||
$this->errors[$scope->name][$property][$error->name] = $expected;
|
||||
// Unset valid flag
|
||||
$this->is_valid = false;
|
||||
}
|
||||
|
||||
// Evaluate an array of Rules property names against scope keys
|
||||
private function eval_strict(Scope $scope): void {
|
||||
$name_diffs = array_diff(array_keys($GLOBALS[$scope->value]), $this->rules_names[$scope->name]);
|
||||
|
||||
// Set errors for each undefined property
|
||||
foreach ($name_diffs as $name_diff) {
|
||||
$this->add_error(Error::UNKNOWN_PROPERTY_NAME, $scope, $name_diff, null);
|
||||
}
|
||||
|
||||
// Unset strict mode property now that we have evaled it up to this point
|
||||
$this->strict = null;
|
||||
}
|
||||
|
||||
// Evaluate Rules against a given value
|
||||
|
@ -91,23 +121,52 @@
|
|||
|
||||
// Perform request processing on GET properties (search parameters)
|
||||
public function GET(array $rules): void {
|
||||
// (Re)enable strict mode if property is null
|
||||
if ($this->strict === null) {
|
||||
$this->strict = true;
|
||||
}
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
$this->rules_names[Scope::GET->name][] = $rule->get_property_name();
|
||||
|
||||
$this->eval_rules($rule, Scope::GET);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform request processing on POST properties (request body)
|
||||
public function POST(array $rules): void {
|
||||
// (Re)enable strict mode if property is null
|
||||
if ($this->strict === null) {
|
||||
$this->strict = true;
|
||||
}
|
||||
|
||||
foreach ($rules as $rule) {
|
||||
$this->rules_names[Scope::POST->name][] = $rule->get_property_name();
|
||||
|
||||
$this->eval_rules($rule, Scope::POST);
|
||||
}
|
||||
}
|
||||
|
||||
public function is_valid(): bool {
|
||||
return empty($this->errors);
|
||||
}
|
||||
// ----
|
||||
|
||||
// Return array of all set Errors
|
||||
public function get_errors(): array {
|
||||
// Strict mode is enabled
|
||||
if ($this->strict === true) {
|
||||
$this->eval_strict(Scope::GET);
|
||||
$this->eval_strict(Scope::POST);
|
||||
}
|
||||
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function is_valid(): bool {
|
||||
// Strict mode is enabled
|
||||
if ($this->strict === true) {
|
||||
$this->eval_strict(Scope::GET);
|
||||
$this->eval_strict(Scope::POST);
|
||||
}
|
||||
|
||||
return $this->is_valid;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue