From 06816d5f52c0ea2813d49673e673bae25897dee7 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 7 Mar 2016 22:00:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=85=85=E7=A7=BB?= =?UTF-8?q?=E5=87=BAValidate=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/think/Model.php | 139 +++++++++++++++++- library/think/Validate.php | 124 +--------------- tests/thinkphp/library/think/validateTest.php | 52 ------- 3 files changed, 141 insertions(+), 174 deletions(-) diff --git a/library/think/Model.php b/library/think/Model.php index 7cbfb054..06bdfec4 100644 --- a/library/think/Model.php +++ b/library/think/Model.php @@ -988,8 +988,6 @@ class Model */ protected function dataValidate(&$data) { - // 验证前清空error - $this->error = ''; if (!empty($this->options['validate'])) { if (!empty($this->rule)) { Validate::rule($this->rule); @@ -1012,11 +1010,146 @@ class Model protected function dataFill(&$data) { if (!empty($this->options['auto'])) { - Validate::fill($data, $this->options['auto']); + // 获取自动完成规则 + list($rules, $options, $scene) = $this->getDataRule($this->options['auto']); + + foreach ($rules as $key => $val) { + if (is_numeric($key) && is_array($val)) { + $key = array_shift($val); + } + if (!empty($scene) && !in_array($key, $scene)) { + continue; + } + // 数据自动填充 + $this->fillItem($key, $val, $data, $options); + } $this->options['auto'] = null; } } + /** + * 获取数据自动完成的规则定义 + * @access protected + * @param mixed $rules 数据规则 + * @return array + */ + protected function getDataRule($rules) + { + if (is_string($rules)) { + // 读取配置定义 + $config = Config::get('auto'); + if (strpos($rules, '.')) { + list($name, $group) = explode('.', $rules); + } else { + $name = $rules; + } + $rules = isset($config[$name]) ? $config[$name] : []; + if (isset($config['__all__'])) { + $rules = array_merge($config['__all__'], $rules); + } + } + if (isset($rules['__option__'])) { + // 参数设置 + $options = $rules['__option__']; + unset($rules['__option__']); + } else { + $options = []; + } + if (isset($group) && isset($options['scene'][$group])) { + // 如果设置了适用场景 + $scene = $options['scene'][$group]; + if (is_string($scene)) { + $scene = explode(',', $scene); + } + } else { + $scene = []; + } + return [$rules, $options, $scene]; + } + + /** + * 数据自动填充 + * @access protected + * @param string $key 字段名 + * @param mixed $val 填充规则 + * @param array $data 数据 + * @param array $options 参数 + * @return void + */ + protected function fillItem($key, $val, &$data, $options = []) + { + // 获取数据 支持二维数组 + if (strpos($key, '.')) { + list($name1, $name2) = explode('.', $key); + $value = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null; + } else { + $value = isset($data[$key]) ? $data[$key] : null; + } + if ((isset($options['value_fill']) && in_array($key, is_string($options['value_fill']) ? explode(',', $options['value_fill']) : $options['value_fill']) && '' == $value) + || (isset($options['exists_fill']) && in_array($key, is_string($options['exists_fill']) ? explode(',', $options['exists_fill']) : $options['exists_fill']) && is_null($value))) { + // 不满足自动填充条件 + return; + } + if ($val instanceof \Closure) { + $result = call_user_func_array($val, [$value, &$data]); + } elseif (isset($val[0]) && $val[0] instanceof \Closure) { + $result = call_user_func_array($val[0], [$value, &$data]); + } elseif (!is_array($val)) { + $result = $val; + } else { + $rule = isset($val[0]) ? $val[0] : $val; + $type = isset($val[1]) ? $val[1] : 'value'; + $params = isset($val[2]) ? (array) $val[2] : []; + switch ($type) { + case 'behavior': + Hook::exec($rule, '', $data); + return; + case 'callback': + array_unshift($params, $value); + $result = call_user_func_array($rule, $params); + break; + case 'serialize': + if (is_string($rule)) { + $rule = explode(',', $rule); + } + $serialize = []; + foreach ($rule as $name) { + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if (isset($data[$name1][$name2])) { + $serialize[$name] = $data[$name1][$name2]; + unset($data[$name1][$name2]); + } + } elseif (isset($data[$name])) { + $serialize[$name] = $data[$name]; + unset($data[$name]); + } + } + $fun = !empty($params['type']) ? $params['type'] : 'serialize'; + $result = $fun($serialize); + break; + case 'ignore': + if ($rule === $value) { + if (strpos($key, '.')) { + unset($data[$name1][$name2]); + } else { + unset($data[$key]); + } + } + return; + case 'value': + default: + $result = $rule; + break; + } + } + if (strpos($key, '.')) { + $data[$name1][$name2] = $result; + } else { + $data[$key] = $result; + } + } + /** * 切换当前的数据库连接 * @access public diff --git a/library/think/Validate.php b/library/think/Validate.php index 2c7dc0b5..73f32c4e 100644 --- a/library/think/Validate.php +++ b/library/think/Validate.php @@ -105,88 +105,6 @@ class Validate return !empty(self::$error) ? false : true; } - // 自动填充 - public static function fill(&$data, $rules, $config = 'auto') - { - // 获取自动完成规则 - list($rules, $options, $scene) = self::getDataRule($rules, $config); - - foreach ($rules as $key => $val) { - if (is_numeric($key) && is_array($val)) { - $key = array_shift($val); - } - if (!empty($scene) && !in_array($key, $scene)) { - continue; - } - // 数据自动填充 - self::fillItem($key, $val, $data, $options); - } - return $data; - } - - /** - * 数据自动填充 - * @access protected - * @param string $key 字段名 - * @param mixed $val 填充规则 - * @param array $data 数据 - * @param array $options 参数 - * @return void - */ - protected static function fillItem($key, $val, &$data, $options = []) - { - // 获取数据 支持二维数组 - $value = self::getDataValue($data, $key); - if (strpos($key, '.')) { - list($name1, $name2) = explode('.', $key); - } - if ((isset($options['value_fill']) && in_array($key, is_string($options['value_fill']) ? explode(',', $options['value_fill']) : $options['value_fill']) && '' == $value) - || (isset($options['exists_fill']) && in_array($key, is_string($options['exists_fill']) ? explode(',', $options['exists_fill']) : $options['exists_fill']) && is_null($value))) { - // 不满足自动填充条件 - return; - } - if ($val instanceof \Closure) { - $result = self::callback($value, $val, $data); - } elseif (isset($val[0]) && $val[0] instanceof \Closure) { - $result = self::callback($value, $val[0], $data); - } elseif (!is_array($val)) { - $result = $val; - } else { - $rule = isset($val[0]) ? $val[0] : $val; - $type = isset($val[1]) ? $val[1] : 'value'; - $params = isset($val[2]) ? (array) $val[2] : []; - switch ($type) { - case 'behavior': - self::behavior($rule, $data); - return; - case 'callback': - $result = self::callback($value, $rule, $data, $params); - break; - case 'serialize': - $result = self::serialize($value, $rule, $data, $params); - break; - case 'ignore': - if ($rule === $value) { - if (strpos($key, '.')) { - unset($data[$name1][$name2]); - } else { - unset($data[$key]); - } - } - return; - case 'value': - default: - $result = $rule; - break; - } - } - if (strpos($key, '.')) { - $data[$name1][$name2] = $result; - } else { - $data[$key] = $result; - } - } - /** * 验证字段规则 * @access protected @@ -213,7 +131,7 @@ class Validate // 行为验证 $result = self::behavior($rule, $data); break; - case 'filter': // 使用filter_var验证 + case 'filter': // 使用filter_var验证 $result = self::filter($value, $rule, $options); break; case 'confirm': @@ -225,10 +143,10 @@ class Validate case 'notin': $result = self::notin($value, $rule); break; - case 'between': // 验证是否在某个范围 + case 'between': // 验证是否在某个范围 $result = self::between($value, $rule); break; - case 'notbetween': // 验证是否不在某个范围 + case 'notbetween': // 验证是否不在某个范围 $result = self::notbetween($value, $rule); break; case 'expire': @@ -267,7 +185,7 @@ class Validate } /** - * 使用callback方式验证或者填充 + * 使用callback方式验证 * @access public * @param mixed $value 字段值 * @param mixed $rule 验证规则 @@ -285,7 +203,7 @@ class Validate } /** - * 使用行为类验证或者填充 + * 使用行为类验证 * @access public * @param mixed $rule 验证规则 * @param array $data 数据 @@ -293,41 +211,9 @@ class Validate */ public static function behavior($rule, $data) { - // 行为验证 return Hook::exec($rule, '', $data); } - /** - * 序列化填充 - * @access public - * @param mixed $value 字段值 - * @param mixed $rule 验证规则 - * @param array $data 数据 - * @param array $params 参数 - * @return mixed - */ - public static function serialize($value, $rule, &$data, $params = []) - { - if (is_string($rule)) { - $rule = explode(',', $rule); - } - $serialize = []; - foreach ($rule as $name) { - if (strpos($name, '.')) { - list($name1, $name2) = explode('.', $name); - if (isset($data[$name1][$name2])) { - $serialize[$name] = $data[$name1][$name2]; - unset($data[$name1][$name2]); - } - } elseif (isset($data[$name])) { - $serialize[$name] = $data[$name]; - unset($data[$name]); - } - } - $fun = !empty($params['type']) ? $params['type'] : 'serialize'; - return $fun($serialize); - } - /** * 使用filter_var方式验证 * @access public diff --git a/tests/thinkphp/library/think/validateTest.php b/tests/thinkphp/library/think/validateTest.php index 0d445971..a9db2d1d 100644 --- a/tests/thinkphp/library/think/validateTest.php +++ b/tests/thinkphp/library/think/validateTest.php @@ -98,56 +98,4 @@ class validateTest extends \PHPUnit_Framework_TestCase } } - public function testFill() - { - $data = [ - 'username' => '', - 'nickname' => 'nickname', - 'phone' => ' 123456', - 'hobby' => ['1', '2'], - 'cityid' => '1', - 'a' => 'a', - 'b' => 'b', - ]; - $auto = [ - 'user' => [ - '__option__' => [ - 'value_fill' => ['username', 'password', 'phone'], - 'exists_fill' => 'nickname', - ], - 'username' => ['strtolower', 'callback'], - 'password' => ['md5', 'callback'], - 'nickname' => [[ & $this, 'fillName'], 'callback', 'cn_'], - 'phone' => function ($value, $data) { - return trim($value); - }, - 'ab' => ['a,b', 'serialize'], - 'cityid' => ['1', 'ignore'], - 'address' => ['address'], - 'integral' => 0, - ['reg_time', 'time', 'callback'], - ['login_time', function ($value, $data) { - return $data['reg_time']; - }], - ], - ]; - Config::set('auto', $auto); - $result = Validate::fill($data, 'user'); - $data['nickname'] = 'cn_nickname'; - $data['phone'] = '123456'; - $data['ab'] = serialize(['a' => 'a', 'b' => 'b']); - $data['address'] = 'address'; - $data['integral'] = 0; - $data['reg_time'] = time(); - $data['login_time'] = $data['reg_time']; - unset($data['cityid'], $data['a'], $data['b']); - $this->assertEquals($data, $result); - - } - - public function fillName($value, $prefix) - { - return $prefix . trim($value); - } - }