form.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2017 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package form
  5. import (
  6. "reflect"
  7. "strings"
  8. "github.com/Unknwon/com"
  9. "github.com/go-macaron/binding"
  10. "gopkg.in/macaron.v1"
  11. )
  12. func init() {
  13. binding.SetNameMapper(com.ToSnakeCase)
  14. }
  15. type Form interface {
  16. binding.Validator
  17. }
  18. // Assign assign form values back to the template data.
  19. func Assign(form interface{}, data map[string]interface{}) {
  20. typ := reflect.TypeOf(form)
  21. val := reflect.ValueOf(form)
  22. if typ.Kind() == reflect.Ptr {
  23. typ = typ.Elem()
  24. val = val.Elem()
  25. }
  26. for i := 0; i < typ.NumField(); i++ {
  27. field := typ.Field(i)
  28. fieldName := field.Tag.Get("form")
  29. // Allow ignored fields in the struct
  30. if fieldName == "-" {
  31. continue
  32. } else if len(fieldName) == 0 {
  33. fieldName = com.ToSnakeCase(field.Name)
  34. }
  35. data[fieldName] = val.Field(i).Interface()
  36. }
  37. }
  38. func getRuleBody(field reflect.StructField, prefix string) string {
  39. for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
  40. if strings.HasPrefix(rule, prefix) {
  41. return rule[len(prefix) : len(rule)-1]
  42. }
  43. }
  44. return ""
  45. }
  46. func getSize(field reflect.StructField) string {
  47. return getRuleBody(field, "Size(")
  48. }
  49. func getMinSize(field reflect.StructField) string {
  50. return getRuleBody(field, "MinSize(")
  51. }
  52. func getMaxSize(field reflect.StructField) string {
  53. return getRuleBody(field, "MaxSize(")
  54. }
  55. func getInclude(field reflect.StructField) string {
  56. return getRuleBody(field, "Include(")
  57. }
  58. func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors {
  59. if errs.Len() == 0 {
  60. return errs
  61. }
  62. data["HasError"] = true
  63. Assign(f, data)
  64. typ := reflect.TypeOf(f)
  65. val := reflect.ValueOf(f)
  66. if typ.Kind() == reflect.Ptr {
  67. typ = typ.Elem()
  68. val = val.Elem()
  69. }
  70. for i := 0; i < typ.NumField(); i++ {
  71. field := typ.Field(i)
  72. fieldName := field.Tag.Get("form")
  73. // Allow ignored fields in the struct
  74. if fieldName == "-" {
  75. continue
  76. }
  77. if errs[0].FieldNames[0] == field.Name {
  78. data["Err_"+field.Name] = true
  79. trName := field.Tag.Get("locale")
  80. if len(trName) == 0 {
  81. trName = l.Tr("form." + field.Name)
  82. } else {
  83. trName = l.Tr(trName)
  84. }
  85. switch errs[0].Classification {
  86. case binding.ERR_REQUIRED:
  87. data["ErrorMsg"] = trName + l.Tr("form.require_error")
  88. case binding.ERR_ALPHA_DASH:
  89. data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")
  90. case binding.ERR_ALPHA_DASH_DOT:
  91. data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")
  92. case binding.ERR_SIZE:
  93. data["ErrorMsg"] = trName + l.Tr("form.size_error", getSize(field))
  94. case binding.ERR_MIN_SIZE:
  95. data["ErrorMsg"] = trName + l.Tr("form.min_size_error", getMinSize(field))
  96. case binding.ERR_MAX_SIZE:
  97. data["ErrorMsg"] = trName + l.Tr("form.max_size_error", getMaxSize(field))
  98. case binding.ERR_EMAIL:
  99. data["ErrorMsg"] = trName + l.Tr("form.email_error")
  100. case binding.ERR_URL:
  101. data["ErrorMsg"] = trName + l.Tr("form.url_error")
  102. case binding.ERR_INCLUDE:
  103. data["ErrorMsg"] = trName + l.Tr("form.include_error", getInclude(field))
  104. default:
  105. data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification
  106. }
  107. return errs
  108. }
  109. }
  110. return errs
  111. }