Files
kiri-router/src/Validator/BindForm.php
T

146 lines
4.7 KiB
PHP
Raw Normal View History

2023-04-16 03:38:47 +08:00
<?php
namespace Kiri\Router\Validator;
2023-04-16 13:27:54 +08:00
use Exception;
2023-12-15 19:41:22 +08:00
use Kiri\Di\Inject\Config;
use Kiri\Di\Inject\Container;
2023-04-16 03:38:47 +08:00
use Kiri\Di\Interface\InjectParameterInterface;
2023-04-16 12:44:43 +08:00
use Kiri\Router\Base\Middleware;
2023-12-15 16:14:39 +08:00
use Kiri\Router\Validator\RequestFilter\RequestFilterInterface;
use Kiri\Router\Validator\Types\ArrayProxy;
use Kiri\Router\Validator\Types\BoolProxy;
use Kiri\Router\Validator\Types\FloatProxy;
use Kiri\Router\Validator\Types\IntProxy;
use Kiri\Router\Validator\Types\MixedProxy;
use Kiri\Router\Validator\Types\StringProxy;
use Kiri\Router\Validator\Types\TypesProxy;
2023-12-15 16:33:36 +08:00
use Kiri\Server\ServerInterface;
2023-12-04 21:17:04 +08:00
use ReflectionNamedType;
2023-12-15 19:41:22 +08:00
use ReflectionProperty;
2023-12-04 21:17:04 +08:00
use ReflectionUnionType;
2023-12-15 19:27:21 +08:00
use function inject;
2023-04-16 03:38:47 +08:00
#[\Attribute(\Attribute::TARGET_PARAMETER)]
class BindForm implements InjectParameterInterface
{
2023-11-09 17:04:46 +08:00
/**
* @param string $formValidate
*/
public function __construct(readonly public string $formValidate)
{
}
/**
* @param string $class
* @param string $method
* @return mixed
2023-12-12 15:35:35 +08:00
* @throws
2023-11-09 17:04:46 +08:00
*/
public function dispatch(string $class, string $method): object
{
$validator = new Validator();
2023-11-09 20:33:44 +08:00
$container = \Kiri::getDi();
$reflect = $container->getReflectionClass($this->formValidate);
2023-12-04 21:17:04 +08:00
$object = $validator->setFormData($reflect->newInstanceWithoutConstructor());
2023-11-09 17:04:46 +08:00
foreach ($reflect->getProperties() as $property) {
2023-12-15 19:27:21 +08:00
$ignoring = $property->getAttributes(Ignoring::class);
2023-12-15 19:41:22 +08:00
$comment = $property->getDocComment();
2023-12-15 19:32:31 +08:00
if (count($ignoring) > 0 || ($comment && str_contains($comment, '@deprecated'))) {
2023-12-15 19:28:39 +08:00
continue;
}
2023-12-15 19:41:22 +08:00
$this->properties($validator, $property, $object);
2023-11-09 17:04:46 +08:00
}
2023-11-09 17:38:49 +08:00
$middleware = \instance(ValidatorMiddleware::class);
2023-11-09 17:04:46 +08:00
$middleware->validator = $validator;
2023-11-09 20:33:44 +08:00
$container->get(Middleware::class)->set($class, $method, $middleware);
2023-11-09 17:04:46 +08:00
return $validator->getFormData();
}
2023-04-16 03:38:47 +08:00
2023-12-04 21:17:04 +08:00
/**
2023-12-15 19:41:22 +08:00
* @param Validator $validator
* @param ReflectionProperty $property
* @param object $object
* @return void
* @throws Exception
*/
2023-12-15 19:41:36 +08:00
protected function properties(Validator $validator, ReflectionProperty $property, object $object): void
2023-12-15 19:41:22 +08:00
{
$propertyContainer = $property->getAttributes(Container::class);
if (count($propertyContainer) > 0) {
($propertyContainer[0]->newInstance())->dispatch($object, $property->getName());
}
$propertyConfig = $property->getAttributes(Config::class);
if (count($propertyConfig) > 0) {
($propertyConfig[0]->newInstance())->dispatch($object, $property->getName());
}
$binding = $property->getAttributes(Binding::class);
if (count($binding) > 0) {
/** @var Binding $rule */
$rule = $binding[0]->newInstance();
$validator->addRule($property->getName(), $rule->dispatch($object, $property->getName()));
$validator->setAlias($property->getName(), $rule->field);
}
2023-12-15 19:45:05 +08:00
$validator->addRule($property->getName(), [$this->_typeValidator($property), 'dispatch', false]);
2023-12-15 19:41:22 +08:00
}
/**
* @param ReflectionProperty $property
* @return TypesProxy
2023-12-15 16:14:39 +08:00
* @throws Exception
2023-12-04 21:17:04 +08:00
*/
2023-12-15 19:41:22 +08:00
private function _typeValidator(ReflectionProperty $property): TypesProxy
2023-12-04 21:17:04 +08:00
{
2023-12-15 16:14:39 +08:00
$getType = $property->getType();
2023-12-15 16:33:36 +08:00
if (is_null($getType)) {
$service = \Kiri::getDi();
if ($service->has(ServerInterface::class)) {
$service->get(ServerInterface::class)->shutdown();
}
throw new Exception('Field ' . $property->getDeclaringClass()->getName() . '::' . $property->getName() . ' must have a numerical type set.');
2023-12-04 21:17:04 +08:00
}
2023-12-15 16:33:36 +08:00
$array = ['allowsNull' => $property->getType()->allowsNull()];
if (!$getType instanceof ReflectionUnionType) {
$array = array_merge($array, ['class' => $this->_typeProxy($getType)]);
} else {
$types = [];
foreach ($getType->getTypes() as $type) {
$types[] = $type->getName();
}
$array = array_merge($array, ['types' => $types, 'class' => MixedProxy::class]);
2023-12-15 16:14:39 +08:00
}
2023-12-15 16:33:36 +08:00
return \Kiri::createObject($array);
2023-12-04 21:17:04 +08:00
}
/**
* @param ReflectionNamedType $type
2023-12-15 16:33:36 +08:00
* @return string|null
2023-12-04 21:17:04 +08:00
*/
2023-12-15 16:33:36 +08:00
private function _typeProxy(ReflectionNamedType $type): ?string
2023-12-04 21:17:04 +08:00
{
return match ($type->getName()) {
2023-12-15 16:14:39 +08:00
'array' => ArrayProxy::class,
'bool' => BoolProxy::class,
'float' => FloatProxy::class,
'int' => IntProxy::class,
'string' => StringProxy::class,
2023-12-15 16:33:36 +08:00
default => null
2023-12-04 21:17:04 +08:00
};
}
2023-04-16 03:38:47 +08:00
}