diff --git a/validation/README.md b/validation/README.md index e0c30df7..5c3212b0 100644 --- a/validation/README.md +++ b/validation/README.md @@ -41,7 +41,7 @@ Direct Use: } } // or use like this - if v := valid.Max(u.Age, 140); !v.Ok { + if v := valid.Max(u.Age, 140, "ageMax"); !v.Ok { log.Println(v.Error.Key, v.Error.Message) } } @@ -63,7 +63,48 @@ Struct Tag Use: } func main() { - valid := Validation{} + valid := validation.Validation{} + u := user{Name: "test", Age: 40} + b, err := valid.Valid(u) + if err != nil { + // handle error + } + if !b { + // validation does not pass + // blabla... + } + } + +Use custom function: + + import ( + "github.com/astaxie/beego/validation" + ) + + type user struct { + Id int + Name string `valid:"Required;IsMe"` + Age int `valid:"Required;Range(1, 140)"` + } + + func IsMe(v *validation.Validation, obj interface{}, key string) { + name, ok:= obj.(string) + if !ok { + // wrong use case? + return + } + + if name != "me" { + // valid false + v.SetError("Name", "is not me!") + } + } + + func main() { + valid := validation.Validation{} + if err := validation.AddCustomFunc("IsMe", IsMe); err != nil { + // hadle error + } u := user{Name: "test", Age: 40} b, err := valid.Valid(u) if err != nil { diff --git a/validation/util.go b/validation/util.go index 9e4f642d..7c3fd20c 100644 --- a/validation/util.go +++ b/validation/util.go @@ -56,6 +56,27 @@ func init() { } } +type CustomFunc func(v *Validation, obj interface{}, key string) + +// Add a custom function to validation +// The name can not be: +// Clear +// HasErrors +// ErrorMap +// Error +// Check +// Valid +// NoMatch +// If the name is same with exists function, it will replace the origin valid function +func AddCustomFunc(name string, f CustomFunc) error { + if unFuncs[name] { + return fmt.Errorf("invalid function name: %s", name) + } + + funcs[name] = reflect.ValueOf(f) + return nil +} + // ValidFunc Valid function type type ValidFunc struct { Name string @@ -102,7 +123,6 @@ func getValidFuncs(f reflect.StructField) (vfs []ValidFunc, err error) { return } if vfs, tag, err = getRegFuncs(tag, f.Name); err != nil { - fmt.Printf("%+v\n", err) return } fs := strings.Split(tag, ";") @@ -214,7 +234,7 @@ func trim(name, key string, s []string) (ts []interface{}, err error) { for i := 0; i < len(s); i++ { var param interface{} // skip *Validation and obj params - if param, err = magic(fn.Type().In(i+2), strings.TrimSpace(s[i])); err != nil { + if param, err = parseParam(fn.Type().In(i+2), strings.TrimSpace(s[i])); err != nil { return } ts[i] = param @@ -224,7 +244,7 @@ func trim(name, key string, s []string) (ts []interface{}, err error) { } // modify the parameters's type to adapt the function input parameters' type -func magic(t reflect.Type, s string) (i interface{}, err error) { +func parseParam(t reflect.Type, s string) (i interface{}, err error) { switch t.Kind() { case reflect.Int: i, err = strconv.Atoi(s) diff --git a/validation/validation.go b/validation/validation.go index 76683d91..2b020aa8 100644 --- a/validation/validation.go +++ b/validation/validation.go @@ -38,7 +38,7 @@ // } // } // // or use like this -// if v := valid.Max(u.Age, 140); !v.Ok { +// if v := valid.Max(u.Age, 140, "ageMax"); !v.Ok { // log.Println(v.Error.Key, v.Error.Message) // } // } diff --git a/validation/validators.go b/validation/validators.go index 2662b701..9d9df467 100644 --- a/validation/validators.go +++ b/validation/validators.go @@ -46,6 +46,38 @@ var MessageTmpls = map[string]string{ "ZipCode": "Must be valid zipcode", } +// set default messages +// if not set, the default messages are +// "Required": "Can not be empty", +// "Min": "Minimum is %d", +// "Max": "Maximum is %d", +// "Range": "Range is %d to %d", +// "MinSize": "Minimum size is %d", +// "MaxSize": "Maximum size is %d", +// "Length": "Required length is %d", +// "Alpha": "Must be valid alpha characters", +// "Numeric": "Must be valid numeric characters", +// "AlphaNumeric": "Must be valid alpha or numeric characters", +// "Match": "Must match %s", +// "NoMatch": "Must not match %s", +// "AlphaDash": "Must be valid alpha or numeric or dash(-_) characters", +// "Email": "Must be a valid email address", +// "IP": "Must be a valid ip address", +// "Base64": "Must be valid base64 characters", +// "Mobile": "Must be valid mobile number", +// "Tel": "Must be valid telephone number", +// "Phone": "Must be valid telephone or mobile phone number", +// "ZipCode": "Must be valid zipcode", +func SetDefaultMessage(msg map[string]string) { + if len(msg) == 0 { + return + } + + for name := range msg { + MessageTmpls[name] = msg[name] + } +} + // Validator interface type Validator interface { IsSatisfied(interface{}) bool @@ -556,7 +588,7 @@ func (b Base64) GetLimitValue() interface{} { } // just for chinese mobile phone number -var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][067]|[4][579]))\\d{8}$") +var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|[8][0-9]|[7][0679]|[4][579]))\\d{8}$") // Mobile check struct type Mobile struct {