解析验证规则

@param string $rules 验证规则 e.g. required;string,max:30;string,length:1-3
@param string $field 需要验证的字段

@return array e.g.
[
[$field, 'required'],
[$field, 'string', 'max' => 30],
[$field, 'string', 'length' => [1,3]]
]
555673
protected function parseRulesToArray($rules, $field)
    {
        $value = [];
        if (!empty($rules)) {
            // 获取所有规则
            $array = preg_split('/[;\r\n]+/', trim($rules, ";\r\n"));
            if (!empty($array)) {
                foreach ($array as $key => $val) {
                    $value[$key][] = $field; // [$field]
                    $tmp = explode(',', $val);
                    $value[$key][] = $tmp[0]; // [$field, 'required']|[$field, 'string']
                    array_shift($tmp);  // $tmp = max:30|length:1-3
                    foreach ($tmp as $k => $v) {
                        if (strpos($v, ':')) {
                            $t = explode(':', $v);
                            if (strpos($t[1], '-')) {
                                $value[$key][$t[0]] = explode('-', $t[1]); // [$field, 'string', 'length' => [1,3]]
                            } else {
                                $value[$key][$t[0]] = intval($t[1]); // [$field, 'string', 'max' => 30]
                            }
                        }
                    }
                }
            }
        }
        
        return $value;
    }
755267
function in($field, $ins)
    {
        if (is_array($ins))
        {
            $ins = implode(',', $ins);
        }
        else
        {
            //去掉两边的分号
            $ins = trim($ins, ',');
        }
        $this->where("`$field` IN ({$ins})");
    }
1006439
public function max($field) {
        $this->statementContext->setFields("MAX({$field}) AS __MAX__");
        $row = $this->findOne();

        //SQL执行发生错误
        if ($row === false) {
            return false;
        }

        return $row['__MAX__'];
    }
497440
protected function createRules($field, $rules)
    {
        $rule = str_replace(['(', ')', ';'], [':', '', ','], implode('|', $rules));

        if ($this->scaffold) {
            $rule = 'required';
        }

        return "\t\t\t'{$field}' => '".$rule."',".PHP_EOL;
    }
854595
public function parse($value, $rule) {
        $callback = isset($rule['callback']) 
            ? $rule['callback'] 
            : (isset($rule['callable']) ? $rule['callable'] : NULL);

        // 提前触发回调类的加载，以便能正常回调
        if (is_array($callback) && count($callback) >= 2 && is_string($callback[0])) {
            // Type 2：静态类方法，如：array('MyClass', 'myCallbackMethod')
            class_exists($callback[0]);
        } else if (is_string($callback) && preg_match('/(.*)\:\:/', $callback, $macthes)) {
            // Type 4：静态类方法，如：'MyClass::myCallbackMethod'
            class_exists($macthes[1]);
        }

        if (empty($callback) || !is_callable($callback)) {
            throw new InternalServerErrorException(
                \PhalApi\T('invalid callback for rule: {name}', array('name' => $rule['name']))
            );
        }

        if (isset($rule['params'])) {
            return call_user_func($callback, $value, $rule, $rule['params']);
        } else {
            return call_user_func($callback, $value, $rule);
        }
    }
868822
protected function getRule($attribute, $rules)
	{
		if ( ! array_key_exists($attribute, $this->rules))
		{
			return;
		}

		$rules = (array) $rules;

		foreach ($this->rules[$attribute] as $rule)
		{
			list($rule, $parameters) = $this->parseRule($rule);

			if (in_array($rule, $rules)) return [$rule, $parameters];
		}
	}
1187935
public function min($field) {
        $this->statementContext->setFields("MIN({$field}) AS __MIN__");
        $row = $this->findOne();

        //SQL执行发生错误
        if ($row === false) {
            return false;
        }

        return $row['__MIN__'];
    }
242546
public function col($fields, $where = null, $orderBy = null, $limit = null): array
    {
        // 按Select进行查询
        $table = self::selectArray($fields, $where, $orderBy, $limit);

        // 如果没有查到
        if (!$table) {
            return [];
        }

        // 保存返回值
        $ret = [];

        // 取所有的列名
        $keys = array_keys($table[0]);

        // 取第一个列名
        $key = $keys[0];

        // 逐个循环,取出一列的值
        foreach ($table as $row) {
            $ret[] = $row[$key];
        }

        // 返回一列
        return $ret;
    }
1068263
protected function maxValidate($value, $rule)
    {
        if (is_array($value)) {
            $length = count($value);
        }else {
            $length = mb_strlen((string) $value);
        }
        return $length <= $rule;
    }
1027904
public function validate($all = false, $data = null, $rules = null)
	{
		if (null === $data)
		{
			$data = $this->data;
		}
		if (null === $rules)
		{
			$rules = $this->rule;
		}
		$this->result = array ();
		foreach ($rules as $rule)
		{
			// 规则合法性判断
			if (isset($rule['name']))
			{
				if (empty($rule['type']))
				{ // 无类型就不需要验证
					continue;
				}
				if (! isset($rule['msg']))
				{
					$rule['msg'] = false;
				}
			}
			else
			{
				if (count($rule) < 3)
				{
					throw new Exception(Lang::get('VAL_ARGS_LESS'));
					break;
				}
				$t = $rule;
				$rule = array ();
				// 直接传值处理
				$rule['name'] = $t[0];
				$rule['msg'] = $t[1];
				$rule['type'] = $t[2];
			}
			// 同名参数失败一次就不继续验证
			if (isset($this->result[$rule['name']]))
			{
				continue;
			}
			// 验证类型支持字符串方式
			if (! is_array($rule['type']))
			{
				$rule['type'] = explode(',', $rule['type']);
			}
			foreach ($rule['type'] as $k => $v)
			{
				// 验证方法传值处理
				if (is_numeric($k))
				{
					$type = $v;
					$args = array ($type);
				}
				else
				{
					$type = $k;
					$args = array_merge(array ($type), $v);
				}
				// 规则验证类型为是否存在
				if ('required' === $type)
				{
					$result = $this->required($rule['name'], $data);
				}
				else if ($this->required($rule['name'], $data))
				{
					// 值
					array_unshift($args, $data[$rule['name']]);
					// 调用验证方法
					$result = call_user_func_array(array ('self','check'), $args);
				}
				else
				{
					// 值不存在
					$result = false;
				}
				// 判断验证失败
				if (! $result)
				{
					if ($all)
					{
						$this->result[$rule['name']] = array ('name' => $rule['name'],'msg' => $rule['msg']);
					}
					else
					{
						$this->result = array ('name' => $rule['name'],'msg' => $rule['msg']);
						return $this->result;
					}
					break;
				}
			}
		}
		return $this->result;
	}
658510
private function formatRule($rules)
    {
        if (is_array($rules)) {
            foreach ($rules as $rule) {
                $formatted[] = $this->formatRule($rule);
            }

            return $formatted ?? [];
        }

        if (is_object($rules) || is_callable($rules)) {
            return $rules;
        }

        if (Str::contains($rules, 'required_if') && preg_match('/(.*):(.*),(.*)/', $rules, $matches)) {
            $column = Str::startsWith($matches[2], '*.') ? $matches[2] : '*.' . $matches[2];

            return $matches[1] . ':' . $column . ',' . $matches[3];
        }

        return $rules;
    }
1094342
public function fromForm($rule = 'default', $all = false)
	{
		// 获取规则
		if (! is_array($rule))
		{
			if (isset($this->rules[$rule]))
			{
				$rule = $this->rules[$rule];
			}
			else
			{
				return false;
			}
		}
		// 清空当前数据
		$this->data = array ();
		// 循环获取数据
		foreach ($rule as $value)
		{
			// 规则合法性判断
			if (isset($value['name']))
			{
				// 处理没有传入from的情况
				if (! isset($value['table']))
				{
					$value['table'] = '';
				}
			}
			else
			{
				// 判断数量是否正确
				if (count($value) < 3)
				{
					throw new Exception(Lang::get('MODEL_FORM_ARGS_LESS'));
					break;
				}
				$t = $value;
				$value = array ();
				// 直接传值处理
				$value['name'] = $t[0];
				if (isset($t[3]))
				{
					$value['table'] = $t[3];
				}
				else
				{
					$value['table'] = '';
				}
			}
			// 获取数据
			$d = Request::getAll($value['table'], $value['name']);
			// 判断获取是否成功
			if (false === $d)
			{
				// 判断是否有默认值
				if(array_key_exists('default',$value))
				{
					$this->data[$value['name']] = $value['default'];
				}
			}
			else
			{
				// 过滤器支持
				if(isset($value['filter']))
				{
					$this->data[$value['name']] = execFilter($d,$value['filter']);
				}
				else
				{
					$this->data[$value['name']] = execFilter($d,Config::get('@.DEFAULT_FILTER'));
				}
			}
		}
		// 开始验证
		$v = new Validator();
		// 保存验证结果
		$result = $v->validate($all, $this->data, $rule);
		if (array () === $result)
		{ // 验证通过
		  // 字段映射
			$this->data = $this->parseFieldsMap($this->data);
			return true;
		}
		else
		{
			// 清空数据
			$this->data = array ();
			// 返回验证结果
			return $result;
		}
	}
1181399
protected function parseRule($rule)
	{
		$parameters = array();

		// The format for specifying validation rules and parameters follows an
		// easy {rule}:{parameters} formatting convention. For instance the
		// rule "Max:3" states that the value may only be three letters.
		if (strpos($rule, ':') !== false)
		{
			list($rule, $parameter) = explode(':', $rule, 2);

			$parameters = $this->parseParameters($rule, $parameter);
		}

		return array(studly_case($rule), $parameters);
	}
1169667
public function rule($rule, $fields, ...$params)
    {
        if (\is_callable($rule)
            && !(\is_string($rule) && $this->hasValidator($rule))
        ) {
            $name = $this->getUniqueRuleName($fields);
            $message = $params[0] ?? null;
            $this->addInstanceRule($name, $rule, $message);
            $rule = $name;
        }

        $errors = $this->getRules();
        if (!isset($errors[$rule])) {
            $ruleMethod = 'validate' . \ucfirst($rule);
            if (!\method_exists($this, $ruleMethod)) {
                throw new \InvalidArgumentException("Rule '" . $rule . "' has not been registered with " . __CLASS__ . "::addRule().");
            }
        }

        // Ensure rule has an accompanying message
        $messages = $this->getRuleMessages();
        $message = $messages[$rule] ?? self::ERROR_DEFAULT;

        // Ensure message contains field label
        if (\strpos($message, '{field}') === false) {
            $message = '{field} ' . $message;
        }

        $this->_validations[] = [
            'rule' => $rule,
            'fields' => (array) $fields,
            'params' => (array) $params,
            'message' => '{field} ' . $message,
            'skip' => self::SKIP_CONTINUE,
        ];

        return $this;
    }
777830
public function validator($field, array $data)
    {
        $value = isset($data[$field]) ? $data[$field] : null;
        if ($value === '' || $value === null) {
            return $this->allowEmpty ? true : $this->message('{fieldName}不在允许的范围内！', [
                '{fieldName}' => $this->getName($field),
            ], 'emptyMsg');
        }

        if (in_array($value, $this->range, $this->isStrict)) {
            return true;
        }

        return $this->message('{fieldName}不在允许的范围内！', [
            '{fieldName}' => $this->getName($field),
        ]);
    }
138952
final public function getValidationRule($field): array
    {
        $rules = $this->rules();
        $response = [];

        foreach ($rules as $rule) {
            if (Any::isArray($rule[0])) { // 2 or more rules [['field1', 'field2'], 'filter', 'filter_argv']
                foreach ($rule[0] as $tfield) {
                    if ($tfield == $field) {
                        $response[$rule[1]] = $rule[2];
                    } // ['min_length' => 1, 'required' => null]
                }
            } else { // 1 rule ['field1', 'filter', 'filter_argv']
                if ($rule[0] === $field) {
                    $response[$rule[1]] = $rule[2];
                }
            }
        }

        return $response;
    }
1351020
public function rules()
    {
        return [
            ['username', 'required', '帐号不能为空', Validate::MUST_VALIDATE],
            ['password', 'required', '密码不能为空', Validate::EXISTS_VALIDATE],
            ['code', 'captcha', '验证码输入错误', Validate::EXISTS_VALIDATE],
        ];
    }