/
callback.go
101 lines (86 loc) · 2.96 KB
/
callback.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package media_library
import (
"bytes"
"encoding/json"
"errors"
"mime/multipart"
"github.com/disintegration/imaging"
"github.com/jinzhu/gorm"
)
func SaveAndCropImage(isCreate bool) func(scope *gorm.Scope) {
return func(scope *gorm.Scope) {
if !scope.HasError() {
var updateColumns = map[string]interface{}{}
for _, field := range scope.Fields() {
if media, ok := field.Field.Addr().Interface().(MediaLibrary); ok && !media.Cropped() {
option := parseTagOption(field.Tag.Get("media_library"))
if media.GetFileHeader() != nil || media.NeedCrop() {
var file multipart.File
var err error
if fileHeader := media.GetFileHeader(); fileHeader != nil {
file, err = media.GetFileHeader().Open()
} else {
file, err = media.Retrieve(media.URL("original"))
}
if scope.Err(err) != nil {
return
}
media.Cropped(true)
if url := media.GetURL(option, scope, field, media); url == "" {
scope.Err(errors.New("invalid URL"))
} else {
result, _ := json.Marshal(map[string]string{"Url": url})
media.Scan(string(result))
}
if isCreate {
if value, err := media.Value(); err == nil {
updateColumns[field.DBName] = value
}
}
if file != nil {
defer file.Close()
if media.IsImage() {
// Save Original Image
if scope.Err(media.Store(media.URL("original"), option, file)) == nil {
file.Seek(0, 0)
// Crop & Resize
if img, err := imaging.Decode(file); scope.Err(err) == nil {
if format, err := getImageFormat(media.URL()); scope.Err(err) == nil {
if cropOption := media.GetCropOption("original"); cropOption != nil {
img = imaging.Crop(img, *cropOption)
}
// Save default image
var buffer bytes.Buffer
imaging.Encode(&buffer, img, *format)
media.Store(media.URL(), option, &buffer)
for key, size := range media.GetSizes() {
newImage := img
if cropOption := media.GetCropOption(key); cropOption != nil {
newImage = imaging.Crop(newImage, *cropOption)
}
dst := imaging.Thumbnail(newImage, size.Width, size.Height, imaging.Lanczos)
var buffer bytes.Buffer
imaging.Encode(&buffer, dst, *format)
media.Store(media.URL(key), option, &buffer)
}
}
}
}
} else {
// Save File
scope.Err(media.Store(media.URL(), option, file))
}
}
}
}
}
if isCreate && !scope.HasError() && len(updateColumns) != 0 {
scope.NewDB().Model(scope.Value).UpdateColumns(updateColumns)
}
}
}
}
func init() {
gorm.DefaultCallback.Update().Before("gorm:before_update").Register("media_library:save_and_crop", SaveAndCropImage(false))
gorm.DefaultCallback.Create().After("gorm:after_create").Register("media_library:save_and_crop", SaveAndCropImage(true))
}