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.
Application-Web/src/Http/HttpRequest.php

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.");
}
}