/
controller.go
125 lines (105 loc) · 3.97 KB
/
controller.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package publish
import (
"bytes"
"fmt"
"html/template"
"net/http"
"os"
"path"
"reflect"
"strings"
"github.com/qor/qor/admin"
"github.com/qor/qor/utils"
)
type publishController struct {
*Publish
}
func (db *publishController) Preview(context *admin.Context) {
drafts := make(map[*admin.Resource]interface{})
draftDB := context.GetDB().Set("publish:draft_mode", true).Unscoped()
for _, res := range context.Admin.GetResources() {
if !res.Config.Invisible {
results := res.NewSlice()
if isPublishableModel(res.Value) {
if draftDB.Where("publish_status = ?", DIRTY).Find(results).RowsAffected > 0 {
drafts[res] = results
}
}
}
}
context.Execute("publish/drafts", drafts)
}
func (db *publishController) Diff(context *admin.Context) {
resourceID := strings.Split(context.Request.URL.Path, "/")[4]
params := strings.Split(resourceID, "__")
name, id := params[0], params[1]
res := context.Admin.GetResource(name)
draft := res.NewStruct()
context.GetDB().Set("publish:draft_mode", true).Unscoped().First(draft, id)
production := res.NewStruct()
context.GetDB().Set("publish:draft_mode", false).Unscoped().First(production, id)
results := map[string]interface{}{"Production": production, "Draft": draft, "Resource": res}
fmt.Fprintf(context.Writer, string(context.Render("publish/diff", results)))
}
func (db *publishController) PublishOrDiscard(context *admin.Context) {
var request = context.Request
var ids = request.Form["checked_ids[]"]
var records = []interface{}{}
var values = map[string][]string{}
for _, id := range ids {
if keys := strings.Split(id, "__"); len(keys) == 2 {
name, id := keys[0], keys[1]
values[name] = append(values[name], id)
}
}
draftDB := context.GetDB().Set("publish:draft_mode", true).Unscoped()
for name, value := range values {
res := context.Admin.GetResource(name)
results := res.NewSlice()
if draftDB.Find(results, fmt.Sprintf("%v IN (?)", res.PrimaryDBName()), value).Error == nil {
resultValues := reflect.Indirect(reflect.ValueOf(results))
for i := 0; i < resultValues.Len(); i++ {
records = append(records, resultValues.Index(i).Interface())
}
}
}
if request.Form.Get("publish_type") == "publish" {
Publish{DB: draftDB}.Publish(records...)
} else if request.Form.Get("publish_type") == "discard" {
Publish{DB: draftDB}.Discard(records...)
}
http.Redirect(context.Writer, context.Request, context.Request.RequestURI, http.StatusFound)
}
var injected bool
func (publish *Publish) InjectQorAdmin(res *admin.Resource) {
if !injected {
injected = true
for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/qor/publish/views"))
}
}
res.UseTheme("publish")
controller := publishController{publish}
router := res.GetAdmin().GetRouter()
router.Get(fmt.Sprintf("^/%v/diff/", res.ToParam()), controller.Diff)
router.Get(fmt.Sprintf("^/%v", res.ToParam()), controller.Preview)
router.Post(fmt.Sprintf("^/%v", res.ToParam()), controller.PublishOrDiscard)
res.GetAdmin().RegisterFuncMap("render_publish_meta", func(value interface{}, meta *admin.Meta, context *admin.Context) template.HTML {
var err error
var result = bytes.NewBufferString("")
var tmpl = template.New(meta.Type + ".tmpl").Funcs(context.FuncMap())
if tmpl, err = context.FindTemplate(tmpl, fmt.Sprintf("metas/publish/%v.tmpl", meta.Type)); err != nil {
if tmpl, err = context.FindTemplate(tmpl, fmt.Sprintf("metas/index/%v.tmpl", meta.Type)); err != nil {
tmpl, _ = tmpl.Parse("{{.Value}}")
}
}
data := map[string]interface{}{"Value": context.ValueOf(value, meta), "Meta": meta}
if err := tmpl.Execute(result, data); err != nil {
utils.ExitWithMsg(err.Error())
}
return template.HTML(result.String())
})
res.GetAdmin().RegisterFuncMap("publish_unique_key", func(res *admin.Resource, record interface{}, context *admin.Context) string {
return fmt.Sprintf("%s__%v", res.ToParam(), context.GetDB().NewScope(record).PrimaryKeyValue())
})
}