@@ -6,8 +6,14 @@ package user
6
6
import (
7
7
"context"
8
8
"fmt"
9
+ "net/url"
10
+ "strings"
9
11
10
12
"code.gitea.io/gitea/models/db"
13
+ "code.gitea.io/gitea/modules/setting"
14
+
15
+ "xorm.io/builder"
16
+ "xorm.io/xorm"
11
17
)
12
18
13
19
// Badge represents a user badge
@@ -30,6 +36,10 @@ func init() {
30
36
db .RegisterModel (new (UserBadge ))
31
37
}
32
38
39
+ func AdminCreateBadge (ctx context.Context , badge * Badge ) error {
40
+ return CreateBadge (ctx , badge )
41
+ }
42
+
33
43
// GetUserBadges returns the user's badges.
34
44
func GetUserBadges (ctx context.Context , u * User ) ([]* Badge , int64 , error ) {
35
45
sess := db .GetEngine (ctx ).
@@ -42,9 +52,30 @@ func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
42
52
return badges , count , err
43
53
}
44
54
55
+ // GetBadgeUsers returns the badges users.
56
+ func GetBadgeUsers (ctx context.Context , b * Badge ) ([]* User , int64 , error ) {
57
+ sess := db .GetEngine (ctx ).
58
+ Select ("`user`.*" ).
59
+ Join ("INNER" , "user_badge" , "`user_badge`.user_id=user.id" ).
60
+ Where ("user_badge.badge_id=?" , b .ID )
61
+
62
+ users := make ([]* User , 0 , 8 )
63
+ count , err := sess .FindAndCount (& users )
64
+ return users , count , err
65
+ }
66
+
45
67
// CreateBadge creates a new badge.
46
68
func CreateBadge (ctx context.Context , badge * Badge ) error {
47
- _ , err := db .GetEngine (ctx ).Insert (badge )
69
+ isExist , err := IsBadgeExist (ctx , 0 , badge .Slug )
70
+
71
+ if err != nil {
72
+ return err
73
+ } else if isExist {
74
+ return ErrBadgeAlreadyExist {badge .Slug }
75
+ }
76
+
77
+ _ , err = db .GetEngine (ctx ).Insert (badge )
78
+
48
79
return err
49
80
}
50
81
@@ -58,9 +89,22 @@ func GetBadge(ctx context.Context, slug string) (*Badge, error) {
58
89
return badge , err
59
90
}
60
91
92
+ // GetBadgeByID returns a badge
93
+ func GetBadgeByID (ctx context.Context , id int64 ) (* Badge , error ) {
94
+ badge := new (Badge )
95
+ has , err := db .GetEngine (ctx ).Where ("id=?" , id ).Get (badge )
96
+ if err != nil {
97
+ return nil , err
98
+ } else if ! has {
99
+ return nil , ErrBadgeNotExist {ID : id }
100
+ }
101
+
102
+ return badge , err
103
+ }
104
+
61
105
// UpdateBadge updates a badge based on its slug.
62
106
func UpdateBadge (ctx context.Context , badge * Badge ) error {
63
- _ , err := db .GetEngine (ctx ).Where ("slug =?" , badge .Slug ).Update (badge )
107
+ _ , err := db .GetEngine (ctx ).Where ("id =?" , badge .ID ). Cols ( "slug" , "description" , "image_url" ).Update (badge )
64
108
return err
65
109
}
66
110
@@ -70,6 +114,15 @@ func DeleteBadge(ctx context.Context, badge *Badge) error {
70
114
return err
71
115
}
72
116
117
+ // DeleteUserBadgeRecord deletes a user badge record.
118
+ func DeleteUserBadgeRecord (ctx context.Context , badge * Badge ) error {
119
+ userBadge := & UserBadge {
120
+ BadgeID : badge .ID ,
121
+ }
122
+ _ , err := db .GetEngine (ctx ).Where ("badge_id=?" , userBadge .BadgeID ).Delete (userBadge )
123
+ return err
124
+ }
125
+
73
126
// AddUserBadge adds a badge to a user.
74
127
func AddUserBadge (ctx context.Context , u * User , badge * Badge ) error {
75
128
return AddUserBadges (ctx , u , []* Badge {badge })
@@ -122,3 +175,107 @@ func RemoveAllUserBadges(ctx context.Context, u *User) error {
122
175
_ , err := db .GetEngine (ctx ).Where ("user_id=?" , u .ID ).Delete (& UserBadge {})
123
176
return err
124
177
}
178
+
179
+ // HTMLURL returns the badges full link.
180
+ func (u * Badge ) HTMLURL () string {
181
+ return setting .AppURL + url .PathEscape (u .Slug )
182
+ }
183
+
184
+ // IsBadgeExist checks if given badge slug exist,
185
+ // it is used when creating/updating a badge slug
186
+ func IsBadgeExist (ctx context.Context , uid int64 , slug string ) (bool , error ) {
187
+ if len (slug ) == 0 {
188
+ return false , nil
189
+ }
190
+ return db .GetEngine (ctx ).
191
+ Where ("slug!=?" , uid ).
192
+ Get (& Badge {Slug : strings .ToLower (slug )})
193
+ }
194
+
195
+ // SearchBadgeOptions represents the options when fdin badges
196
+ type SearchBadgeOptions struct {
197
+ db.ListOptions
198
+
199
+ Keyword string
200
+ Slug string
201
+ ID int64
202
+ OrderBy db.SearchOrderBy
203
+ Actor * User // The user doing the search
204
+
205
+ ExtraParamStrings map [string ]string
206
+ }
207
+
208
+ func (opts * SearchBadgeOptions ) ToConds () builder.Cond {
209
+ cond := builder .NewCond ()
210
+
211
+ if opts .Keyword != "" {
212
+ cond = cond .And (builder.Like {"badge.slug" , opts .Keyword })
213
+ }
214
+
215
+ return cond
216
+ }
217
+
218
+ func (opts * SearchBadgeOptions ) ToOrders () string {
219
+ orderBy := "badge.slug"
220
+ return orderBy
221
+ }
222
+
223
+ func (opts * SearchBadgeOptions ) ToJoins () []db.JoinFunc {
224
+ return []db.JoinFunc {
225
+ func (e db.Engine ) error {
226
+ e .Join ("INNER" , "badge" , "badge.badge_id = badge.id" )
227
+ return nil
228
+ },
229
+ }
230
+ }
231
+
232
+ func SearchBadges (ctx context.Context , opts * SearchBadgeOptions ) (badges []* Badge , _ int64 , _ error ) {
233
+ sessCount := opts .toSearchQueryBase (ctx )
234
+ defer sessCount .Close ()
235
+ count , err := sessCount .Count (new (Badge ))
236
+ if err != nil {
237
+ return nil , 0 , fmt .Errorf ("count: %w" , err )
238
+ }
239
+
240
+ if len (opts .OrderBy ) == 0 {
241
+ opts .OrderBy = db .SearchOrderByID
242
+ }
243
+
244
+ sessQuery := opts .toSearchQueryBase (ctx ).OrderBy (opts .OrderBy .String ())
245
+ defer sessQuery .Close ()
246
+ if opts .Page != 0 {
247
+ sessQuery = db .SetSessionPagination (sessQuery , opts )
248
+ }
249
+
250
+ // the sql may contain JOIN, so we must only select Badge related columns
251
+ sessQuery = sessQuery .Select ("`badge`.*" )
252
+ badges = make ([]* Badge , 0 , opts .PageSize )
253
+ return badges , count , sessQuery .Find (& badges )
254
+ }
255
+
256
+ func (opts * SearchBadgeOptions ) toSearchQueryBase (ctx context.Context ) * xorm.Session {
257
+ var cond builder.Cond
258
+ cond = builder.Neq {"id" : - 1 }
259
+
260
+ if len (opts .Keyword ) > 0 {
261
+ lowerKeyword := strings .ToLower (opts .Keyword )
262
+ keywordCond := builder .Or (
263
+ builder.Like {"slug" , lowerKeyword },
264
+ builder.Like {"description" , lowerKeyword },
265
+ builder.Like {"id" , lowerKeyword },
266
+ )
267
+ cond = cond .And (keywordCond )
268
+ }
269
+
270
+ if opts .ID > 0 {
271
+ cond = cond .And (builder.Eq {"id" : opts .ID })
272
+ }
273
+
274
+ if len (opts .Slug ) > 0 {
275
+ cond = cond .And (builder.Eq {"slug" : opts .Slug })
276
+ }
277
+
278
+ e := db .GetEngine (ctx )
279
+
280
+ return e .Where (cond )
281
+ }
0 commit comments