Files
hyperf_data/extend/Aether/PHP/Hyperf/AetherValidator.php
2025-09-19 15:14:20 +08:00

134 lines
3.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace Aether;
use Aether\Exception\ValidationFailedException;
use Hyperf\Context\ApplicationContext;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Validator;
use RuntimeException;
abstract class AetherValidator
{
/**
* 当前场景名.
*/
public ?string $currentScene = null;
#[Inject]
protected ValidatorFactoryInterface $validationFactory;
/**
* 待验证数据.
*/
protected array $data = [];
/**
* 自定义验证规则子类可通过该属性注册无需重写registerRules
* 格式:['规则名' => 闭包/类方法].
*/
protected array $customRules = [];
/**
* 静态快捷验证方法(简化调用).
*/
public static function validate(string $scene, array $data = []): array
{
$instance = ApplicationContext::getContainer()->get(static::class);
return $instance->scene($scene, $data)->check();
}
/**
* 设置验证场景和数据(支持链式调用).
*/
public function scene(string $scene, array $data = []): self
{
$this->currentScene = $scene;
$this->data = $data;
return $this;
}
/**
* 执行验证(失败抛出异常).
*/
public function check(): array
{
if (empty($this->currentScene)) {
throw new RuntimeException('请先设置验证场景');
}
$scenes = $this->scenes();
if (! isset($scenes[$this->currentScene])) {
throw new RuntimeException("验证场景不存在:{$this->currentScene}");
}
$sceneConfig = $scenes[$this->currentScene];
return $this->validateData(
$this->data,
$sceneConfig['rules'],
$sceneConfig['messages'] ?? [],
$sceneConfig['attributes'] ?? []
);
}
/**
* 格式化验证错误信息(统一格式,供异常处理器复用).
*/
public function formatValidationErrors(Validator $validator): array
{
$errors = [];
$failedRules = $validator->failed();
$errorMessages = $validator->errors()->getMessages();
$attributes = $validator->attributes();
foreach ($failedRules as $field => $rules) {
$errors[] = [
'field' => $field,
'field_label' => $attributes[$field] ?? $field,
'message' => $errorMessages[$field][0] ?? '',
'rules' => array_keys($rules),
'value' => $validator->getValue($field),
];
}
return $errors;
}
/**
* 实际执行验证的逻辑(重命名方法名更清晰).
*/
protected function validateData(array $data, array $rules, array $messages = [], array $attributes = []): array
{
$validator = $this->validationFactory->make($data, $rules, $messages, $attributes);
$this->registerRules($validator);
if ($validator->fails()) {
throw new ValidationFailedException(
$validator,
$this->currentScene ?? '',
$validator->errors()->first()
);
}
return $validator->validated();
}
/**
* 自动注册自定义规则(优先使用$customRules属性.
*/
protected function registerRules(Validator $validator): void
{
foreach ($this->customRules as $ruleName => $rule) {
$validator->extend($ruleName, $rule);
}
}
/**
* 定义场景验证规则(子类实现).
*/
abstract protected function scenes(): array;
}