github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/forum.go (about) 1 package common 2 3 import ( 4 //"log" 5 "database/sql" 6 "errors" 7 "strconv" 8 "strings" 9 10 qgen "github.com/Azareal/Gosora/query_gen" 11 _ "github.com/go-sql-driver/mysql" 12 ) 13 14 // TODO: Do we really need this? 15 type ForumAdmin struct { 16 ID int 17 Name string 18 Desc string 19 Active bool 20 Preset string 21 TopicCount int 22 PresetLang string 23 } 24 25 type Forum struct { 26 ID int 27 Link string 28 Name string 29 Desc string 30 Tmpl string 31 Active bool 32 Order int 33 Preset string 34 ParentID int 35 ParentType string 36 TopicCount int 37 38 LastTopic *Topic 39 LastTopicID int 40 LastReplyer *User 41 LastReplyerID int 42 LastTopicTime string // So that we can re-calculate the relative time on the spot in /forums/ 43 LastPage int 44 } 45 46 // ? - What is this for? 47 type ForumSimple struct { 48 ID int 49 Name string 50 Active bool 51 Preset string 52 } 53 54 type ForumStmts struct { 55 update *sql.Stmt 56 setPreset *sql.Stmt 57 } 58 59 var forumStmts ForumStmts 60 61 func init() { 62 DbInits.Add(func(acc *qgen.Accumulator) error { 63 forumStmts = ForumStmts{ 64 update: acc.Update("forums").Set("name=?,desc=?,active=?,preset=?").Where("fid=?").Prepare(), 65 setPreset: acc.Update("forums").Set("preset=?").Where("fid=?").Prepare(), 66 } 67 return acc.FirstError() 68 }) 69 } 70 71 // Copy gives you a non-pointer concurrency safe copy of the forum 72 func (f *Forum) Copy() (fcopy Forum) { 73 fcopy = *f 74 return fcopy 75 } 76 77 // TODO: Write tests for this 78 func (f *Forum) Update(name, desc string, active bool, preset string) error { 79 if name == "" { 80 name = f.Name 81 } 82 // TODO: Do a line sanitise? Does it matter? 83 preset = strings.TrimSpace(preset) 84 _, err := forumStmts.update.Exec(name, desc, active, preset, f.ID) 85 if err != nil { 86 return err 87 } 88 if f.Preset != preset && preset != "custom" && preset != "" { 89 err = PermmapToQuery(PresetToPermmap(preset), f.ID) 90 if err != nil { 91 return err 92 } 93 } 94 _ = Forums.Reload(f.ID) 95 return nil 96 } 97 98 func (f *Forum) SetPreset(preset string, gid int) error { 99 fp, changed := GroupForumPresetToForumPerms(preset) 100 if changed { 101 return f.SetPerms(fp, preset, gid) 102 } 103 return nil 104 } 105 106 // TODO: Refactor this 107 func (f *Forum) SetPerms(fperms *ForumPerms, preset string, gid int) (err error) { 108 err = ReplaceForumPermsForGroup(gid, map[int]string{f.ID: preset}, map[int]*ForumPerms{f.ID: fperms}) 109 if err != nil { 110 LogError(err) 111 return errors.New("Unable to update the permissions") 112 } 113 114 // TODO: Add this and replaceForumPermsForGroup into a transaction? 115 _, err = forumStmts.setPreset.Exec("", f.ID) 116 if err != nil { 117 LogError(err) 118 return errors.New("Unable to update the forum") 119 } 120 err = Forums.Reload(f.ID) 121 if err != nil { 122 return errors.New("Unable to reload forum") 123 } 124 err = FPStore.Reload(f.ID) 125 if err != nil { 126 return errors.New("Unable to reload the forum permissions") 127 } 128 return nil 129 } 130 131 // TODO: Replace this sorting mechanism with something a lot more efficient 132 // ? - Use sort.Slice instead? 133 type SortForum []*Forum 134 135 func (sf SortForum) Len() int { 136 return len(sf) 137 } 138 func (sf SortForum) Swap(i, j int) { 139 sf[i], sf[j] = sf[j], sf[i] 140 } 141 142 /*func (sf SortForum) Less(i,j int) bool { 143 l := sf.less(i,j) 144 if l { 145 log.Printf("%s is less than %s. order: %d. id: %d.",sf[i].Name, sf[j].Name, sf[i].Order, sf[i].ID) 146 } else { 147 log.Printf("%s is not less than %s. order: %d. id: %d.",sf[i].Name, sf[j].Name, sf[i].Order, sf[i].ID) 148 } 149 return l 150 }*/ 151 func (sf SortForum) Less(i, j int) bool { 152 if sf[i].Order < sf[j].Order { 153 return true 154 } else if sf[i].Order == sf[j].Order { 155 return sf[i].ID < sf[j].ID 156 } 157 return false 158 } 159 160 // ! Don't use this outside of tests and possibly template_init.go 161 func BlankForum(fid int, link, name, desc string, active bool, preset string, parentID int, parentType string, topicCount int) *Forum { 162 return &Forum{ID: fid, Link: link, Name: name, Desc: desc, Active: active, Preset: preset, ParentID: parentID, ParentType: parentType, TopicCount: topicCount} 163 } 164 165 func BuildForumURL(slug string, fid int) string { 166 if slug == "" || !Config.BuildSlugs { 167 return "/forum/" + strconv.Itoa(fid) 168 } 169 return "/forum/" + slug + "." + strconv.Itoa(fid) 170 } 171 172 func GetForumURLPrefix() string { 173 return "/forum/" 174 }