willow
willow copied to clipboard
Revamp WriteValidatorBase
<?php
declare(strict_types=1);
namespace Willow\Controllers;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Respect\Validation\Validator as V;
use Willow\Middleware\ResponseBody;
abstract class WriteValidatorBase
{
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
{
$responseBody = $this->processValidation($request->getAttribute('response_body'));
// If there are any missing or required data points then we short circuit and return invalid request.
if ($responseBody->hasMissingRequiredOrInvalid()) {
$responseBody = $responseBody
->setStatus(ResponseBody::HTTP_BAD_REQUEST)
->setMessage('Missing or invalid request');
return $responseBody();
}
return $handler->handle($request);
}
/**
* You should override this function to perform the validations
* @param ResponseBody $responseBody
* @return ResponseBody
*/
protected function processValidation(ResponseBody $responseBody): ResponseBody {
return $responseBody;
}
/**
* Default processValidation() for generic validations
* @param ResponseBody $responseBody
* @param array $fields
* @return ResponseBody
*/
protected function defaultValidation(ResponseBody $responseBody, array $fields): ResponseBody {
$parsedRequest = $responseBody->getParsedRequest();
// Iterate all the model fields
foreach($fields as $field => $dataType) {
$protectedField = $dataType[0] === '*';
// Is the model field NOT in the request?
if (!V::key($field)->validate($parsedRequest)) {
// Any dataType proceeded with an * are protected fields and can not be changed (e.g. password_hash)
if ($protectedField) {
continue;
}
// If the request is missing this field so register it as optional
$responseBody->registerParam('optional', $field, $dataType);
} else {
// If Datatype is proceeded with an * it means the field is protected and can not be changed (e.g. password_hash)
if ($protectedField) {
$responseBody->registerParam('invalid', $field, null);
}
// Don't allow emoji characters -- this prevents SQL Errors
if ($dataType === 'string') {
$fieldValue = $parsedRequest[$field];
if (V::notEmpty()->validate($fieldValue) && !V::notEmoji()->validate($fieldValue)) {
$responseBody->registerParam('invalid', $field, 'alpha-numeric. Value given: ' . $fieldValue);
}
}
}
}
return $responseBody;
}
}