mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 20:52:48 +08:00
重写数据自动验证和自动填充
This commit is contained in:
@@ -52,6 +52,8 @@ class Model
|
||||
protected $scope = [];
|
||||
// 字段映射定义
|
||||
protected $map = [];
|
||||
// 字段验证规则定义
|
||||
protected $rule = [];
|
||||
|
||||
/**
|
||||
* 架构函数
|
||||
@@ -193,8 +195,8 @@ class Model
|
||||
protected function _write_data($data, $type)
|
||||
{
|
||||
if (empty($data)) {
|
||||
// 没有传递数据,获取当前数据对象的值
|
||||
if (!empty($this->data)) {
|
||||
// 没有传递数据,获取当前数据对象的值
|
||||
$data = $this->data;
|
||||
// 重置数据
|
||||
$this->data = [];
|
||||
@@ -915,21 +917,11 @@ class Model
|
||||
throw new Exception('invalid data type');
|
||||
}
|
||||
|
||||
// 状态
|
||||
$pk = $this->getPk();
|
||||
$type = $type ? $type : (is_string($pk) && !empty($data[$pk]) ? self::MODEL_UPDATE : self::MODEL_INSERT);
|
||||
|
||||
// 检测提交字段的合法性
|
||||
if (isset($this->options['field'])) {
|
||||
// $this->field('field1,field2...')->create()
|
||||
$fields = $this->options['field'];
|
||||
unset($this->options['field']);
|
||||
} elseif (self::MODEL_INSERT == $type && isset($this->insertFields)) {
|
||||
$fields = $this->insertFields;
|
||||
} elseif (self::MODEL_UPDATE == $type && isset($this->updateFields)) {
|
||||
$fields = $this->updateFields;
|
||||
}
|
||||
if (isset($fields)) {
|
||||
if (is_string($fields)) {
|
||||
$fields = explode(',', $fields);
|
||||
}
|
||||
@@ -939,8 +931,59 @@ class Model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 数据自动验证
|
||||
if (!empty($this->options['validate'])) {
|
||||
if (is_string($this->options['validate'])) {
|
||||
// 读取配置文件中的自动验证定义
|
||||
$validate = Config::get('validate');
|
||||
if (isset($validate['__pattern__'])) {
|
||||
// 全局字段规则
|
||||
$this->rule = $validate['__pattern__'];
|
||||
}
|
||||
$rules = $validate[$this->options['validate']];
|
||||
if (isset($validate['__all__'])) {
|
||||
$rules = array_merge($validate['__all__'], $rules);
|
||||
}
|
||||
} else {
|
||||
$rules = $this->options['validate'];
|
||||
}
|
||||
foreach ($rules as $key => $val) {
|
||||
$value = isset($data[$key]) ? $data[$key] : null;
|
||||
if ($val instanceof \Closure) {
|
||||
// 匿名函数验证 支持传入当前字段和所有字段两个数据
|
||||
$result = App::invokeFunction($val, [$value, $data]);
|
||||
} else {
|
||||
// 验证字段规则
|
||||
$result = $this->checkValidate($key, $val, $data);
|
||||
}
|
||||
if (true !== $result) {
|
||||
// 没有返回true 则表示验证失败
|
||||
$this->error = $result;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 数据自动填充
|
||||
if (!empty($this->options['auto'])) {
|
||||
if (is_string($this->options['auto'])) {
|
||||
// 读取配置文件中的自动验证定义
|
||||
$auto = Config::get('auto');
|
||||
$rules = $auto[$this->options['auto']];
|
||||
if (isset($auto['__all__'])) {
|
||||
$rules = array_merge($auto['__all__'], $rules);
|
||||
}
|
||||
} else {
|
||||
$rules = $this->options['auto'];
|
||||
}
|
||||
foreach ($rules as $key => $val) {
|
||||
// 数据自动填充
|
||||
$this->autoOperation($key, $val, $data);
|
||||
}
|
||||
}
|
||||
// 过滤创建的数据
|
||||
$this->_create_filter($data);
|
||||
$this->_create_filter($data, $type);
|
||||
// 赋值当前数据对象
|
||||
$this->data = $data;
|
||||
// 返回创建的数据以供其他调用
|
||||
@@ -950,6 +993,97 @@ class Model
|
||||
protected function _create_filter(&$data)
|
||||
{}
|
||||
|
||||
/**
|
||||
* 数据自动填充
|
||||
* @access public
|
||||
* @param string $key 字段名
|
||||
* @param mixed $val 填充规则
|
||||
* @param array $data 数据
|
||||
* @return void
|
||||
*/
|
||||
protected function autoOperation($key, $val, &$data)
|
||||
{
|
||||
$value = isset($data[$key]) ? $data[$key] : null;
|
||||
if ($val instanceof \Closure) {
|
||||
$data[$key] = App::invokeFunction($val, [$value, $data]);
|
||||
} else {
|
||||
$rule = isset($val[0]) ? $val[0] : $val;
|
||||
$type = isset($val[1]) ? $val[1] : 'string';
|
||||
switch ($type) {
|
||||
case 'behavior':
|
||||
Hook::exec($rule, '', $data);
|
||||
break;
|
||||
case 'callback':
|
||||
$data[$key] = call_user_func_array($rule, [$value]);
|
||||
break;
|
||||
case 'ignore':
|
||||
if ($rule === $value) {
|
||||
unset($data[$key]);
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
default:
|
||||
$data[$key] = $rule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段规则
|
||||
* @access public
|
||||
* @param string $key 字段名
|
||||
* @param mixed $val 验证规则
|
||||
* @param array $data 数据
|
||||
* @return string|true
|
||||
*/
|
||||
protected function checkValidate($key, $val, &$data)
|
||||
{
|
||||
$value = isset($data[$key]) ? $data[$key] : null;
|
||||
$rule = $val[0];
|
||||
$msg = isset($val[1]) ? $val[1] : 'data validate error : [ ' . $key . ' ]';
|
||||
$type = isset($val[2]) ? $val[2] : 'regex';
|
||||
$options = isset($val[3]) ? $val[3] : [];
|
||||
switch ($type) {
|
||||
case 'callback':
|
||||
$result = call_user_func_array($rule, [$value]);
|
||||
break;
|
||||
case 'behavior':
|
||||
$result = Hook::exec($rule, '', $data);
|
||||
break;
|
||||
case 'filter': // 使用filter_var验证
|
||||
$result = filter_var($value, is_int($rule) ? $rule : filter_id($rule), $options);
|
||||
break;
|
||||
case 'confirm':
|
||||
$result = $value == $data[$rule];
|
||||
break;
|
||||
case 'in':
|
||||
case 'notin':
|
||||
$range = is_array($rule) ? $rule : explode(',', $rule);
|
||||
$result = 'in' == $type ? in_array($value, $range) : !in_array($value, $range);
|
||||
break;
|
||||
case 'between': // 验证是否在某个范围
|
||||
case 'notbetween': // 验证是否不在某个范围
|
||||
if (is_string($rule)) {
|
||||
$rule = explode(',', $rule);
|
||||
}
|
||||
list($min, $max) = $rule;
|
||||
$result = 'between' == $type ? $value >= $min && $value <= $max : $value < $min || $value > $max;
|
||||
break;
|
||||
case 'regex':
|
||||
default:
|
||||
if (isset($options['rule'])) {
|
||||
$rule = $options['rule'];
|
||||
} elseif (isset($this->rule[$rule])) {
|
||||
$rule = $this->rule[$rule];
|
||||
}
|
||||
$result = 1 === preg_match('/^' . $rule . '$/', (string) $value);
|
||||
break;
|
||||
}
|
||||
// 验证失败返回错误信息
|
||||
return false === $result ? $msg : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换当前的数据库连接
|
||||
* @access public
|
||||
@@ -1671,6 +1805,40 @@ class Model
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段验证
|
||||
* @access public
|
||||
* @param mixed $field 字段名或者验证规则
|
||||
* @param array|null $rule 验证规则
|
||||
* @return Model
|
||||
*/
|
||||
public function validate($field, $rule = null)
|
||||
{
|
||||
if (is_array($field) || is_null($rule)) {
|
||||
$this->options['validate'] = $field;
|
||||
} else {
|
||||
$this->options['validate'][$field] = $rule;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段完成
|
||||
* @access public
|
||||
* @param mixed $field 字段名或者自动完成规则
|
||||
* @param array|null $rule 完成规则
|
||||
* @return Model
|
||||
*/
|
||||
public function auto($field, $rule = null)
|
||||
{
|
||||
if (is_array($field) || is_null($rule)) {
|
||||
$this->options['auto'] = $field;
|
||||
} else {
|
||||
$this->options['auto'][$field] = $rule;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置从主服务器读取数据
|
||||
* @access public
|
||||
|
||||
Reference in New Issue
Block a user