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  }