ValidationCore.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. namespace UCore;
  3. use http\Message;
  4. use UCore\Exception\LogicException;
  5. use UCore\Validator\ConsumeErrorValidator;
  6. use UCore\Validator\ConsumeValidator;
  7. use UCore\Validator\EnumValidator;
  8. use UCore\Validator\PrepareValidator;
  9. use Inhere\Validate\Validation;
  10. /**
  11. * 验证核心类
  12. *
  13. * 提供验证基础功能,包括数据验证、类型转换、错误处理等
  14. */
  15. abstract class ValidationCore extends Validation
  16. {
  17. protected string $name = '';
  18. /**
  19. * 验证成功后的处理器列表
  20. *
  21. * @var ConsumeValidator[]
  22. */
  23. protected array $consumeValidators = [];
  24. /**
  25. * 验证失败后的处理器列表
  26. *
  27. * @var ConsumeErrorValidator[]
  28. */
  29. protected array $consumeErrorValidators = [];
  30. /**
  31. * 数值类型转换配置
  32. *
  33. * @var array<string, string>
  34. */
  35. protected array $cats = [];
  36. /**
  37. * 数据键名和默认值
  38. *
  39. * @return array<string, mixed>
  40. */
  41. public function default(): array
  42. {
  43. return [];
  44. }
  45. /**
  46. * 获取默认值的键名列表
  47. *
  48. * @return array<string>
  49. */
  50. public function keys(): array
  51. {
  52. $default = $this->default();
  53. return array_keys($default);
  54. }
  55. /**
  56. * 获取验证规则
  57. *
  58. * @param array $rules 自定义规则
  59. * @return array
  60. */
  61. public function rules(array $rules = []): array
  62. {
  63. return $this->callCatsRules($rules);
  64. }
  65. /**
  66. * 获取安全数据,使用默认值
  67. *
  68. * @param string|null $key 键名
  69. * @return mixed
  70. */
  71. public function getSafeByDefault(?string $key = null): mixed
  72. {
  73. $de = $this->default();
  74. if ($key === null) {
  75. $res = [];
  76. $keys = array_keys($de);
  77. foreach ($keys as $key) {
  78. $res[$key] = $this->getSafeByDefault($key);
  79. }
  80. return $res;
  81. }
  82. return $this->getSafe($key, $de[$key] ?? null);
  83. }
  84. /**
  85. * 获取原始数据
  86. *
  87. * @return array<string, mixed>
  88. */
  89. public function getSourceData(): array
  90. {
  91. return $this->data;
  92. }
  93. /**
  94. * 使用json数据 进行初始化
  95. *
  96. * @param string $scene 场景
  97. * @return static
  98. */
  99. public static function makeByJson(string $scene = ''): static
  100. {
  101. return new static(request()->json()->all(), [], [], $scene);
  102. }
  103. /**
  104. * 使用Protobuf-Message创建验证器
  105. * @param \Google\Protobuf\Internal\Message $message
  106. * @param $scene
  107. * @return static
  108. */
  109. public static function makeByProrobuf(\Google\Protobuf\Internal\Message $message, $scene = ''): static
  110. {
  111. return new static(json_decode($message->serializeToJsonString(),true), [], [], $scene);
  112. }
  113. /**
  114. * 验证完成,不通过抛异常
  115. *
  116. * @return $this
  117. * @throws \UCore\Exception\ValidateException
  118. */
  119. public function validated(): static
  120. {
  121. $this->validate();
  122. if ($this->isFail()) {
  123. throw new Exception\ValidateException($this, $this->firstError());
  124. }
  125. return $this;
  126. }
  127. /**
  128. * 验证
  129. *
  130. * @param array $onlyChecked 只验证的字段
  131. * @param bool|null $stopOnError 是否在错误时停止
  132. * @return $this
  133. */
  134. public function validate(array $onlyChecked = [], ?bool $stopOnError = null): static
  135. {
  136. parent::validate($onlyChecked, $stopOnError);
  137. if ($this->isOk()) {
  138. $this->consume();
  139. }
  140. if ($this->isFail()) {
  141. $this->consumeError();
  142. }
  143. return $this;
  144. }
  145. /**
  146. * 验证完成,不通过抛异常
  147. *
  148. * @param bool $asObject 是否返回对象
  149. * @return array|object
  150. * @throws \UCore\Exception\ValidateException
  151. */
  152. public function validatedData(bool $asObject = false): array|object
  153. {
  154. $this->validated();
  155. return $this->getSafeData($asObject);
  156. }
  157. /**
  158. * 对需要消费的验证器进行消费
  159. *
  160. * @return void
  161. */
  162. public function consume(): void
  163. {
  164. foreach ($this->consumeValidators as $consumeValidator) {
  165. $consumeValidator->consume();
  166. }
  167. }
  168. /**
  169. * 对错误需要消费的验证器进行消费
  170. *
  171. * @return void
  172. */
  173. public function consumeError(): void
  174. {
  175. foreach ($this->consumeErrorValidators as $consumeValidator) {
  176. $consumeValidator->consumeError();
  177. }
  178. }
  179. /**
  180. * 增加一个正确需要消费的验证器
  181. *
  182. * @param ConsumeValidator $consumeValidator
  183. * @return static
  184. */
  185. public function addConsumeValidator(ConsumeValidator $consumeValidator): static
  186. {
  187. $this->consumeValidators[] = $consumeValidator;
  188. return $this;
  189. }
  190. /**
  191. * 增加一个错误需要消费的验证器
  192. *
  193. * @param ConsumeErrorValidator $consumeValidator
  194. * @return static
  195. */
  196. public function addConsumeErrorValidator(ConsumeErrorValidator $consumeValidator): static
  197. {
  198. $this->consumeErrorValidators[] = $consumeValidator;
  199. return $this;
  200. }
  201. /**
  202. * 是否存在安全键名
  203. *
  204. * @param string $key
  205. * @return bool
  206. */
  207. public function hasSafe(string $key): bool
  208. {
  209. $keys = $this->getSafeKeys();
  210. return in_array($key, $keys);
  211. }
  212. /**
  213. * 获取经过验证的数据
  214. *
  215. * @param string $key
  216. * @param mixed|null $default
  217. * @return mixed
  218. */
  219. public function getSafe(string $key, mixed $default = null): mixed
  220. {
  221. $value = parent::getSafe($key, $default);
  222. $cats = $this->cats[$key] ?? '';
  223. if ($cats) {
  224. return $this->getSafeCats($value, $cats);
  225. }
  226. return $value;
  227. }
  228. /**
  229. * 枚举结果
  230. *
  231. * @param mixed $value
  232. * @param string $enumClass
  233. * @return \BackedEnum|mixed
  234. * @throws LogicException
  235. */
  236. public function getSafeCats(mixed $value, string $enumClass): \BackedEnum
  237. {
  238. if (enum_exists($enumClass)) {
  239. return is_subclass_of($enumClass, \BackedEnum::class)
  240. ? $enumClass::from($value)
  241. : constant($enumClass . '::' . $value);
  242. }
  243. throw new LogicException("转义错误");
  244. }
  245. /**
  246. * 处理枚举的参数
  247. *
  248. * @param array $rules
  249. * @return array
  250. */
  251. protected function callCatsRules(array $rules): array
  252. {
  253. if ($this->cats) {
  254. foreach ($this->cats as $name => $class) {
  255. $rules[] = [
  256. $name, new EnumValidator($this, [ $class ])
  257. ];
  258. }
  259. }
  260. return $rules;
  261. }
  262. /**
  263. * 获取名称
  264. *
  265. * @return string
  266. */
  267. public function getName(): string
  268. {
  269. return $this->name;
  270. }
  271. }