You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.4 KiB
82 lines
2.4 KiB
<?php
|
|
|
|
namespace App\Http;
|
|
|
|
use App\Validation\FieldValidationFail;
|
|
use App\Validation\Validation;
|
|
use App\Validation\ValidationFail;
|
|
use App\Validation\Validator;
|
|
use ArrayAccess;
|
|
use Exception;
|
|
|
|
/**
|
|
* @implements ArrayAccess<string, mixed>
|
|
* */
|
|
class HttpRequest implements ArrayAccess {
|
|
/**
|
|
* @var array<string, mixed>
|
|
*/
|
|
private array $data;
|
|
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
private function __construct(array $data) {
|
|
$this->data = $data;
|
|
}
|
|
|
|
/**
|
|
* Creates a new HttpRequest instance, and ensures that the given request data validates the given schema.
|
|
* This is a simple function that only supports flat schemas (non-composed, the data must only be a k/v array pair.)
|
|
* @param array<string, mixed> $request the request's data
|
|
* @param array<string, ValidationFail> $fails a reference to a failure array, that will contain the reported validation failures.
|
|
* @param array<string, Validator[]> $schema the schema to satisfy. a schema is a simple array with a string key (which is the top-level field name), and a set of validators
|
|
* @return HttpRequest|null the built HttpRequest instance, or null if a field is missing, or if any of the schema validator failed
|
|
*/
|
|
public static function from(array $request, array &$fails, array $schema): ?HttpRequest {
|
|
$failure = false;
|
|
foreach ($schema as $fieldName => $fieldValidators) {
|
|
if (!isset($request[$fieldName])) {
|
|
$fails[] = FieldValidationFail::missing($fieldName);
|
|
$failure = true;
|
|
continue;
|
|
}
|
|
$failure |= Validation::validate($request[$fieldName], $fieldName, $fails, ...$fieldValidators);
|
|
}
|
|
|
|
if ($failure) {
|
|
return null;
|
|
}
|
|
return new HttpRequest($request);
|
|
}
|
|
|
|
public function offsetExists($offset): bool {
|
|
return isset($this->data[$offset]);
|
|
}
|
|
|
|
/**
|
|
* @param $offset
|
|
* @return mixed
|
|
*/
|
|
public function offsetGet($offset) {
|
|
return $this->data[$offset];
|
|
}
|
|
|
|
/**
|
|
* @param $offset
|
|
* @param $value
|
|
* @throws Exception
|
|
*/
|
|
public function offsetSet($offset, $value) {
|
|
throw new Exception("requests are immutable objects.");
|
|
}
|
|
|
|
/**
|
|
* @param $offset
|
|
* @throws Exception
|
|
*/
|
|
public function offsetUnset($offset) {
|
|
throw new Exception("requests are immutable objects.");
|
|
}
|
|
}
|