123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <?php namespace App\Http\Requests;
- // 表单验证
- use App\Exceptions\Api\ValidException;
- use Illuminate\Foundation\Http\FormRequest;
- // 验证器
- use Illuminate\Contracts\Validation\Validator;
- /**
- * 基础验证器
- *
- * 此验证器增加了验证场景的移除与添加等功能
- *
- */
- class BaseRequest extends FormRequest
- {
- // 场景列表
- protected $scenes = [];
- // 当前场景
- protected $currentScene;
- // 是否注入之后自动验证
- protected $autoValidate = false;
- // 场景需要移除的验证规则
- protected $remove = [];
- // 场景需要追加的验证规则
- protected $append = [];
- /**
- * 自动认证
- */
- public function authorize()
- {
- return true;
- }
- /**
- * 设置场景
- * @param string $scene
- * @return $this
- */
- public function scene($scene)
- {
- $this->currentScene = $scene;
- return $this;
- }
- /**
- * 覆盖自动验证方法
- */
- public function validateResolved()
- {
- // 注入之后自动验证开启则执行最终验证方法
- if ($this->autoValidate) $this->handleValidate();
- }
- /**
- * 验证方法
- * @param string $scene
- */
- public function validate($scene = '')
- {
- // 有场景参数。设置场景参数
- if ($scene) $this->currentScene = $scene;
- // 调用最终验证方法
- $this->handleValidate();
- }
- /**
- * 根据场景获取规则
- * @return array|mixed
- */
- public function getRules()
- {
- // 获取验证规则
- $rules = $this->container->call([$this, 'rules']);
- // 创建新规则
- $newRules = [];
- // 如果当前有场景并且存在场景字段,使用场景规则
- if ( $this->currentScene && isset($this->scenes[$this->currentScene]) ) {
- // 如果需要验证的场景字段是数组格式直接使用,否则做字符串切割成数组
- $sceneFields = is_array($this->scenes[$this->currentScene]) ? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);
- // 循环场景字段
- foreach ($sceneFields as $field) {
- // 如果场景字段存在于验证规则中,
- if (array_key_exists($field, $rules)) $newRules[$field] = $rules[$field];
- }
- // 返回新规则
- return $this->handleRules($newRules);
- }
- // 没有场景定义数据,使用原规则
- return $this->handleRules($rules);
- }
- /**
- * 处理规则数据
- *
- * @return array|mixed
- */
- protected function handleRules($rules){
- // 循环需要增加的验证字段
- foreach ($this->append as $key => $rule) {
- // 规则中不存在需要增加的验证字段
- if ( !isset($rules[$key]) ) {
- // 添加到验证规则中
- $rules[$key] = $rule;
- }else{
- // 循环要添加规则数据
- foreach ( $rule as $string ) {
- // 要添加的数据
- $append = explode(':',$string);
- // 临时中转已存在的规则
- $tempRules = [];
- // 循环规则中的数据
- foreach (explode('|',$rules[$key]) as $tkey => $string) {
- // 切割规则与参数
- $temp = explode(':',$string);
- $tempRules[$temp['0']] = isset($temp['1']) ? $temp['1'] : null;
- }
- // 不存在的话,增加参数
- $tempRules[$append[0]] = isset($append['1']) ? $append['1'] : null;
- // 重新写入
- $r = [];
- // 循环规则中的数据
- foreach ( $tempRules as $tkey => $string) {
- $r[] = $tkey.':'.$string;
- }
- // 数据组合
- $rules[$key] = implode('|',$r);
- }
- }
- // 添加后删除
- unset($this->append[$key]);
- }
- // 循环删除的字段
- foreach ($this->remove as $key => $rule) {
- // 规则中存在字段才需要删除
- if ( !isset($rules[$key]) ) continue;
- // 如果字段为空,表示删除所有的验证规则
- if( !$rule ) {
- // 删除掉当前的字段
- unset($rules[$key]);
- // 跳出本次循环
- continue;
- }
- // 当前规则
- $newRule = explode('|',$rules[$key]);
- // 循环要删除规则数据
- foreach ( $rule as $remove ) {
- // 要移除的规则
- $remove = explode(':',$remove);
- // 循环当前规则
- foreach ( $newRule as $tkey => $string) {
- // 切割成数组
- $string = explode(':',$string);
- // 如果是要删除的规则
- if( $string[0] == $remove[0]) unset($newRule[$tkey]);
- }
- }
- // 重新赋值到规则
- $rules[$key] = implode('|',$newRule);
- // 添加后删除
- unset($this->remove[$key]);
- }
- // 返回最终规则
- return $rules;
- }
- /**
- * 移除某个字段的验证规则
- * @access public
- * @param string|array $field 字段名
- * @param mixed $rule 验证规则 null 移除所有规则
- * @return $this
- */
- public function remove($field, $rule = null)
- {
- if (is_array($field)) {
- foreach ($field as $key => $rule) {
- if (is_int($key)) {
- $this->remove($rule);
- } else {
- $this->remove($key, $rule);
- }
- }
- } else {
- if (is_string($rule)) {
- $rule = explode('|', $rule);
- }
- $this->remove[$field] = $rule;
- }
- return $this;
- }
- /**
- * 追加某个字段的验证规则
- * @access public
- * @param string|array $field 字段名
- * @param mixed $rule 验证规则
- * @return $this
- */
- public function append($field, $rule = null)
- {
- if (is_array($field)) {
- foreach ($field as $key => $rule) {
- $this->append($key, $rule);
- }
- } else {
- if (is_string($rule)) {
- $rule = explode('|', $rule);
- }
- $this->append[$field] = $rule;
- }
- return $this;
- }
- /**
- * 覆盖设置 自定义验证器
- * @param $factory
- * @return mixed
- */
- public function validator($factory)
- {
- return $factory->make(
- $this->validationData(),
- $this->getRules(),
- $this->messages(),
- $this->attributes()
- );
- }
- /**
- * 最终验证方法
- *
- */
- protected function handleValidate()
- {
- // 验证前准备
- $this->prepareForValidation();
- // 判断用户是否有请求权限,默认为有,如果没有权限,告知失败
- if (!$this->passesAuthorization()) $this->failedAuthorization();
- // 获取验证对象实例
- $instance = $this->getValidatorInstance();
- // 如果验证失败
- if ($instance->fails()) $this->failedValidation($instance);
- // 验证后处理
- $this->passedValidation();
- }
- /**
- * Handle a failed validation attempt.
- *
- * @param \Illuminate\Contracts\Validation\Validator $validator
- *
- * @throws \Illuminate\Validation\ValidationException
- */
- protected function failedValidation(Validator $validator)
- {
- // 获取提示信息
- $error = empty($validator->errors()->all()[0]) ? '' : $validator->errors()->all()[0];
- // 响应抛出
- throw new ValidException($error,$validator->errors()->toArray());
- }
- }
|