mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
improve package gvalid
This commit is contained in:
13
.example/util/gvalid/gvalid_custom_message.go
Normal file
13
.example/util/gvalid/gvalid_custom_message.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/util/gvalid"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g.I18n().SetLanguage("cn")
|
||||
err := gvalid.Check("", "required", nil)
|
||||
fmt.Println(err.String())
|
||||
}
|
||||
14
.example/util/gvalid/i18n/cn.toml
Normal file
14
.example/util/gvalid/i18n/cn.toml
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
"gf.gvalid.required" = "字段不能为空"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -203,7 +203,7 @@ func checkDataType(content []byte) string {
|
||||
return "yml"
|
||||
} else if (gregex.IsMatch(`^[\s\t\[*\]].?*[\w\-]+\s*=\s*.+`, content) || gregex.IsMatch(`\n[\s\t\[*\]]*[\w\-]+\s*=\s*.+`, content)) && gregex.IsMatch(`\n[\s\t]*[\w\-]+\s*=*\"*.+\"`, content) == false && gregex.IsMatch(`^[\s\t]*[\w\-]+\s*=*\"*.+\"`, content) == false {
|
||||
return "ini"
|
||||
} else if gregex.IsMatch(`^[\s\t]*[\w\-]+\s*=\s*.+`, content) || gregex.IsMatch(`\n[\s\t]*[\w\-]+\s*=\s*.+`, content) {
|
||||
} else if gregex.IsMatch(`^[\s\t]*[\w\-\."]+\s*=\s*.+`, content) || gregex.IsMatch(`\n[\s\t]*[\w\-\."]+\s*=\s*.+`, content) {
|
||||
return "toml"
|
||||
} else {
|
||||
return ""
|
||||
|
||||
@ -66,7 +66,7 @@ type CustomMsg = map[string]interface{}
|
||||
// The sequence tag is like: [alias@]rule[...#msg...]
|
||||
func parseSequenceTag(tag string) (field, rule, msg string) {
|
||||
// Complete sequence tag.
|
||||
// Eg: required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致
|
||||
// Example: required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致
|
||||
match, _ := gregex.MatchString(`\s*((\w+)\s*@){0,1}\s*([^#]+)\s*(#\s*(.*)){0,1}\s*`, tag)
|
||||
return strings.TrimSpace(match[2]), strings.TrimSpace(match[3]), strings.TrimSpace(match[5])
|
||||
}
|
||||
|
||||
@ -236,6 +236,11 @@ func Check(value interface{}, rules string, messages interface{}, params ...inte
|
||||
case "date-format":
|
||||
if _, err := gtime.StrToTimeFormat(val, ruleVal); err == nil {
|
||||
match = true
|
||||
} else {
|
||||
var msg string
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":format", ruleVal, -1)
|
||||
errorMsgs[ruleKey] = msg
|
||||
}
|
||||
|
||||
// Values of two fields should be equal as string.
|
||||
@ -245,6 +250,12 @@ func Check(value interface{}, rules string, messages interface{}, params ...inte
|
||||
match = true
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
var msg string
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":field", ruleVal, -1)
|
||||
errorMsgs[ruleKey] = msg
|
||||
}
|
||||
|
||||
// Values of two fields should not be equal as string.
|
||||
case "different":
|
||||
@ -254,6 +265,12 @@ func Check(value interface{}, rules string, messages interface{}, params ...inte
|
||||
match = false
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
var msg string
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":field", ruleVal, -1)
|
||||
errorMsgs[ruleKey] = msg
|
||||
}
|
||||
|
||||
// Field value should be in range of.
|
||||
case "in":
|
||||
@ -429,11 +446,7 @@ func Check(value interface{}, rules string, messages interface{}, params ...inte
|
||||
// It does nothing if the error message for this rule
|
||||
// is already set in previous validation.
|
||||
if _, ok := errorMsgs[ruleKey]; !ok {
|
||||
if msg, ok := customMsgMap[ruleKey]; ok {
|
||||
errorMsgs[ruleKey] = msg
|
||||
} else {
|
||||
errorMsgs[ruleKey] = getDefaultErrorMessageByRule(ruleKey)
|
||||
}
|
||||
errorMsgs[ruleKey] = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
@ -43,8 +43,10 @@ func CheckStruct(object interface{}, rules interface{}, messages ...CustomMsg) *
|
||||
continue
|
||||
}
|
||||
if len(msg) > 0 {
|
||||
ruleArray := strings.Split(rule, "|")
|
||||
msgArray := strings.Split(msg, "|")
|
||||
var (
|
||||
msgArray = strings.Split(msg, "|")
|
||||
ruleArray = strings.Split(rule, "|")
|
||||
)
|
||||
for k, v := range ruleArray {
|
||||
// If length of custom messages is lesser than length of rules,
|
||||
// the rest rules use the default error messages.
|
||||
|
||||
@ -51,21 +51,24 @@ var defaultMessages = map[string]string{
|
||||
"integer": "The :attribute value must be an integer",
|
||||
"float": "The :attribute value must be a float",
|
||||
"boolean": "The :attribute value field must be true or false",
|
||||
"same": "The :attribute value must be the same as field :other",
|
||||
"different": "The :attribute value must be different from field :other",
|
||||
"same": "The :attribute value must be the same as field :field",
|
||||
"different": "The :attribute value must be different from field :field",
|
||||
"in": "The :attribute value is not in acceptable range",
|
||||
"not-in": "The :attribute value is not in acceptable range",
|
||||
"regex": "The :attribute value is invalid",
|
||||
}
|
||||
|
||||
// getDefaultErrorMessageByRule retrieves and returns the default error message
|
||||
// for specified rule. It firstly retrieves the message from i18n manager, it returns
|
||||
// from default error messages if it's not found in i18n manager.
|
||||
func getDefaultErrorMessageByRule(rule string) string {
|
||||
i18nKey := fmt.Sprintf(`gf.gvalid.%s`, rule)
|
||||
content := gi18n.GetContent(i18nKey)
|
||||
// getErrorMessageByRule retrieves and returns the error message for specified rule.
|
||||
// It firstly retrieves the message from custom message map, and then checks i18n manager,
|
||||
// it returns the default error message if it's not found in custom message map or i18n manager.
|
||||
func getErrorMessageByRule(ruleKey string, customMsgMap map[string]string) string {
|
||||
content := customMsgMap[ruleKey]
|
||||
if content != "" {
|
||||
return content
|
||||
}
|
||||
content = gi18n.GetContent(fmt.Sprintf(`gf.gvalid.%s`, ruleKey))
|
||||
if content == "" {
|
||||
content = defaultMessages[rule]
|
||||
content = defaultMessages[ruleKey]
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
@ -43,11 +43,7 @@ func checkLength(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
}
|
||||
}
|
||||
if valueLen < min || valueLen > max {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
|
||||
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
|
||||
return msg
|
||||
@ -56,11 +52,7 @@ func checkLength(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
case "min-length":
|
||||
if min, err := strconv.Atoi(ruleVal); err == nil {
|
||||
if valueLen < min {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
|
||||
}
|
||||
} else {
|
||||
@ -70,11 +62,7 @@ func checkLength(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
case "max-length":
|
||||
if max, err := strconv.Atoi(ruleVal); err == nil {
|
||||
if valueLen > max {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -36,11 +36,7 @@ func checkRange(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
}
|
||||
if v, err := strconv.ParseFloat(value, 10); err == nil {
|
||||
if v < min || v > max {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
|
||||
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
|
||||
}
|
||||
@ -53,11 +49,7 @@ func checkRange(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
if min, err := strconv.ParseFloat(ruleVal, 10); err == nil {
|
||||
if v, err := strconv.ParseFloat(value, 10); err == nil {
|
||||
if v < min {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
|
||||
}
|
||||
} else {
|
||||
@ -72,11 +64,7 @@ func checkRange(value, ruleKey, ruleVal string, customMsgMap map[string]string)
|
||||
if max, err := strconv.ParseFloat(ruleVal, 10); err == nil {
|
||||
if v, err := strconv.ParseFloat(value, 10); err == nil {
|
||||
if v > max {
|
||||
if v, ok := customMsgMap[ruleKey]; !ok {
|
||||
msg = getDefaultErrorMessageByRule(ruleKey)
|
||||
} else {
|
||||
msg = v
|
||||
}
|
||||
msg = getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
|
||||
}
|
||||
} else {
|
||||
|
||||
43
util/gvalid/i18n/cn/validation.toml
Normal file
43
util/gvalid/i18n/cn/validation.toml
Normal file
@ -0,0 +1,43 @@
|
||||
"gf.gvalid.required" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-if" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-unless" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-with" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-with-all" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-without" = ":attribute字段不能为空"
|
||||
"gf.gvalid.required-without-all" = ":attribute字段不能为空"
|
||||
"gf.gvalid.date" = ":attribute日期格式不正确"
|
||||
"gf.gvalid.date-format" = ":attribute日期格式不满足:format"
|
||||
"gf.gvalid.email" = ":attribute邮箱地址格式不正确"
|
||||
"gf.gvalid.phone" = ":attribute手机号码格式不正确"
|
||||
"gf.gvalid.telephone" = ":attribute电话号码格式不正确"
|
||||
"gf.gvalid.passport" = ":attribute账号格式不合法,必需以字母开头,只能包含字母、数字和下划线,长度在6~18之间"
|
||||
"gf.gvalid.password" = ":attribute密码格式不合法,密码格式为任意6-18位的可见字符"
|
||||
"gf.gvalid.password2" = ":attribute密码格式不合法,密码格式为任意6-18位的可见字符,必须包含大小写字母和数字"
|
||||
"gf.gvalid.password3" = ":attribute密码格式不合法,密码格式为任意6-18位的可见字符,必须包含大小写字母、数字和特殊字符"
|
||||
"gf.gvalid.postcode" = ":attribute邮政编码不正确"
|
||||
"gf.gvalid.resident-id" = ":attribute身份证号码格式不正确"
|
||||
"gf.gvalid.bank-card" = ":attribute银行卡号格式不正确"
|
||||
"gf.gvalid.qq" = ":attributeQQ号码格式不正确"
|
||||
"gf.gvalid.ip" = ":attributeIP地址格式不正确"
|
||||
"gf.gvalid.ipv4" = ":attributeIPv4地址格式不正确"
|
||||
"gf.gvalid.ipv6" = ":attributeIPv6地址格式不正确"
|
||||
"gf.gvalid.mac" = ":attributeMAC地址格式不正确"
|
||||
"gf.gvalid.url" = ":attributeURL地址格式不正确"
|
||||
"gf.gvalid.domain" = ":attribute域名格式不正确"
|
||||
"gf.gvalid.length" = ":attribute字段长度为:min到:max个字符"
|
||||
"gf.gvalid.min-length" = ":attribute字段最小长度为:min"
|
||||
"gf.gvalid.max-length" = ":attribute字段最大长度为:max"
|
||||
"gf.gvalid.between" = ":attribute字段大小为:min到:max"
|
||||
"gf.gvalid.min" = ":attribute字段最小值为:min"
|
||||
"gf.gvalid.max" = ":attribute字段最大值为:max"
|
||||
"gf.gvalid.json" = ":attribute字段应当为JSON格式"
|
||||
"gf.gvalid.xml" = ":attribute字段应当为XML格式"
|
||||
"gf.gvalid.array" = ":attribute字段应当为数组"
|
||||
"gf.gvalid.integer" = ":attribute字段应当为整数"
|
||||
"gf.gvalid.float" = ":attribute字段应当为浮点数"
|
||||
"gf.gvalid.boolean" = ":attribute字段应当为布尔值"
|
||||
"gf.gvalid.same" = ":attribute字段值必须和:field相同"
|
||||
"gf.gvalid.different" = ":attribute字段值不能与:field相同"
|
||||
"gf.gvalid.in" = ":attribute字段值不合法"
|
||||
"gf.gvalid.not-in" = ":attribute字段值不合法"
|
||||
"gf.gvalid.regex" = ":attribute字段值不合法"
|
||||
43
util/gvalid/i18n/en/validation.toml
Normal file
43
util/gvalid/i18n/en/validation.toml
Normal file
@ -0,0 +1,43 @@
|
||||
"gf.gvalid.required" = "The :attribute field is required"
|
||||
"gf.gvalid.required-if" = "The :attribute field is required"
|
||||
"gf.gvalid.required-unless" = "The :attribute field is required"
|
||||
"gf.gvalid.required-with" = "The :attribute field is required"
|
||||
"gf.gvalid.required-with-all" = "The :attribute field is required"
|
||||
"gf.gvalid.required-without" = "The :attribute field is required"
|
||||
"gf.gvalid.required-without-all" = "The :attribute field is required"
|
||||
"gf.gvalid.date" = "The :attribute value is not a valid date"
|
||||
"gf.gvalid.date-format" = "The :attribute value does not match the format :format"
|
||||
"gf.gvalid.email" = "The :attribute value must be a valid email address"
|
||||
"gf.gvalid.phone" = "The :attribute value must be a valid phone number"
|
||||
"gf.gvalid.telephone" = "The :attribute value must be a valid telephone number"
|
||||
"gf.gvalid.passport" = "The :attribute value is not a valid passport format"
|
||||
"gf.gvalid.password" = "The :attribute value is not a valid passport format"
|
||||
"gf.gvalid.password2" = "The :attribute value is not a valid passport format"
|
||||
"gf.gvalid.password3" = "The :attribute value is not a valid passport format"
|
||||
"gf.gvalid.postcode" = "The :attribute value is not a valid passport format"
|
||||
"gf.gvalid.resident-id" = "The :attribute value is not a valid resident id number"
|
||||
"gf.gvalid.bank-card" = "The :attribute value must be a valid bank card number"
|
||||
"gf.gvalid.qq" = "The :attribute value must be a valid QQ number"
|
||||
"gf.gvalid.ip" = "The :attribute value must be a valid IP address"
|
||||
"gf.gvalid.ipv4" = "The :attribute value must be a valid IPv4 address"
|
||||
"gf.gvalid.ipv6" = "The :attribute value must be a valid IPv6 address"
|
||||
"gf.gvalid.mac" = "The :attribute value must be a valid MAC address"
|
||||
"gf.gvalid.url" = "The :attribute value must be a valid URL address"
|
||||
"gf.gvalid.domain" = "The :attribute value must be a valid domain format"
|
||||
"gf.gvalid.length" = "The :attribute value length must be between :min and :max"
|
||||
"gf.gvalid.min-length" = "The :attribute value length must be equal or greater than :min"
|
||||
"gf.gvalid.max-length" = "The :attribute value length must be equal or lesser than :max"
|
||||
"gf.gvalid.between" = "The :attribute value must be between :min and :max"
|
||||
"gf.gvalid.min" = "The :attribute value must be equal or greater than :min"
|
||||
"gf.gvalid.max" = "The :attribute value must be equal or lesser than :max"
|
||||
"gf.gvalid.json" = "The :attribute value must be a valid JSON string"
|
||||
"gf.gvalid.xml" = "The :attribute value must be a valid XML string"
|
||||
"gf.gvalid.array" = "The :attribute value must be an array"
|
||||
"gf.gvalid.integer" = "The :attribute value must be an integer"
|
||||
"gf.gvalid.float" = "The :attribute value must be a float"
|
||||
"gf.gvalid.boolean" = "The :attribute value field must be true or false"
|
||||
"gf.gvalid.same" = "The :attribute value must be the same as field :field"
|
||||
"gf.gvalid.different" = "The :attribute value must be different from field :field"
|
||||
"gf.gvalid.in" = "The :attribute value is not in acceptable range"
|
||||
"gf.gvalid.not-in" = "The :attribute value is not in acceptable range"
|
||||
"gf.gvalid.regex" = "The :attribute value is invalid"
|
||||
Reference in New Issue
Block a user