b8146ae485
Add minimum quotas for users to earn the ability to create custom forums. The entry requirements that could earn the first forum include: 1. Having a Certified account status for at least 45 days. 2. Having written 10 posts or replies in the forums. Additional quota is granted in increasing difficulty based on the count of forum posts created. Other changes: * Admin view of Manage Forums can filter for official/community. * "Certified Since" now shown on profile pages. * Update FAQ page for Forums feature.
202 lines
6.0 KiB
Go
202 lines
6.0 KiB
Go
package forum
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/config"
|
|
"code.nonshy.com/nonshy/website/pkg/models"
|
|
"code.nonshy.com/nonshy/website/pkg/session"
|
|
"code.nonshy.com/nonshy/website/pkg/templates"
|
|
)
|
|
|
|
// AddEdit page.
|
|
func AddEdit() http.HandlerFunc {
|
|
tmpl := templates.Must("forum/add_edit.html")
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Are we editing a forum or creating a new one?
|
|
var editID uint64
|
|
if editStr := r.FormValue("id"); editStr != "" {
|
|
if i, err := strconv.Atoi(editStr); err == nil {
|
|
editID = uint64(i)
|
|
} else {
|
|
session.FlashError(w, r, "Edit parameter: id was not an integer")
|
|
templates.Redirect(w, "/forum/admin")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Get the current user.
|
|
currentUser, err := session.CurrentUser(r)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Couldn't get current user: %s", err)
|
|
templates.Redirect(w, "/")
|
|
return
|
|
}
|
|
|
|
// If editing, look up the existing forum.
|
|
var forum *models.Forum
|
|
if editID > 0 {
|
|
if found, err := models.GetForum(editID); err != nil {
|
|
session.FlashError(w, r, "Couldn't get forum: %s", err)
|
|
templates.Redirect(w, "/forum/admin")
|
|
return
|
|
} else {
|
|
// Do we have permission?
|
|
if !found.CanEdit(currentUser) {
|
|
templates.ForbiddenPage(w, r)
|
|
return
|
|
}
|
|
|
|
forum = found
|
|
}
|
|
}
|
|
|
|
// If we are over our quota for User Forums, do not allow creating a new one.
|
|
if forum == nil && !currentUser.HasAdminScope(config.ScopeForumAdmin) && currentUser.ForumQuotaRemaining() <= 0 {
|
|
session.FlashError(w, r, "You do not currently have spare quota to create a new forum.")
|
|
templates.Redirect(w, "/forum/admin")
|
|
return
|
|
}
|
|
|
|
// Saving?
|
|
if r.Method == http.MethodPost {
|
|
var (
|
|
title = strings.TrimSpace(r.PostFormValue("title"))
|
|
fragment = strings.TrimSpace(strings.ToLower(r.PostFormValue("fragment")))
|
|
description = strings.TrimSpace(r.PostFormValue("description"))
|
|
category = strings.TrimSpace(r.PostFormValue("category"))
|
|
isExplicit = r.PostFormValue("explicit") == "true"
|
|
isPrivileged = r.PostFormValue("privileged") == "true"
|
|
isPermitPhotos = r.PostFormValue("permit_photos") == "true"
|
|
isPrivate = r.PostFormValue("private") == "true"
|
|
)
|
|
|
|
// Sanity check admin-only settings -> default these to OFF.
|
|
if !currentUser.HasAdminScope(config.ScopeForumAdmin) {
|
|
isPrivileged = false
|
|
isPermitPhotos = false
|
|
isPrivate = false
|
|
}
|
|
|
|
// Were we editing an existing forum?
|
|
if forum != nil {
|
|
diffs := []models.FieldDiff{
|
|
models.NewFieldDiff("Title", forum.Title, title),
|
|
models.NewFieldDiff("Description", forum.Description, description),
|
|
models.NewFieldDiff("Category", forum.Category, category),
|
|
models.NewFieldDiff("Explicit", forum.Explicit, isExplicit),
|
|
}
|
|
|
|
forum.Title = title
|
|
forum.Description = description
|
|
forum.Category = category
|
|
forum.Explicit = isExplicit
|
|
|
|
// Forum Admin-only options: if the current viewer is not a forum admin, do not change these settings.
|
|
// e.g.: the front-end checkboxes are hidden and don't want to accidentally unset these!
|
|
if currentUser.HasAdminScope(config.ScopeForumAdmin) {
|
|
diffs = append(diffs,
|
|
models.NewFieldDiff("Privileged", forum.Privileged, isPrivileged),
|
|
models.NewFieldDiff("PermitPhotos", forum.PermitPhotos, isPermitPhotos),
|
|
models.NewFieldDiff("Private", forum.Private, isPrivate),
|
|
)
|
|
forum.Privileged = isPrivileged
|
|
forum.PermitPhotos = isPermitPhotos
|
|
forum.Private = isPrivate
|
|
}
|
|
|
|
// Save it.
|
|
if err := forum.Save(); err == nil {
|
|
session.Flash(w, r, "Forum has been updated!")
|
|
templates.Redirect(w, "/forum/admin")
|
|
|
|
// Log the change.
|
|
models.LogUpdated(currentUser, nil, "forums", forum.ID, "Updated the forum's settings.", diffs)
|
|
return
|
|
} else {
|
|
session.FlashError(w, r, "Error saving the forum: %s", err)
|
|
}
|
|
} else {
|
|
// Validate the fragment. Front-end enforces the pattern so this
|
|
// is just a sanity check.
|
|
if m := FragmentRegexp.FindStringSubmatch(fragment); m == nil {
|
|
session.FlashError(w, r, "The fragment format is invalid.")
|
|
templates.Redirect(w, "/forum/admin")
|
|
return
|
|
}
|
|
|
|
// Ensure the fragment is unique.
|
|
if _, err := models.ForumByFragment(fragment); err == nil {
|
|
session.FlashError(w, r, "The forum fragment is already in use.")
|
|
} else {
|
|
// Create the forum.
|
|
forum = &models.Forum{
|
|
Owner: *currentUser,
|
|
Category: category,
|
|
Fragment: fragment,
|
|
Title: title,
|
|
Description: description,
|
|
Explicit: isExplicit,
|
|
Privileged: isPrivileged,
|
|
PermitPhotos: isPermitPhotos,
|
|
Private: isPrivate,
|
|
}
|
|
|
|
if err := models.CreateForum(forum); err == nil {
|
|
session.Flash(w, r, "The forum has been created!")
|
|
templates.Redirect(w, "/forum/admin")
|
|
|
|
// Log the change.
|
|
models.LogCreated(currentUser, "forums", forum.ID, fmt.Sprintf(
|
|
"Created a new forum.\n\n"+
|
|
"* Category: %s\n"+
|
|
"* Title: %s\n"+
|
|
"* Fragment: %s\n"+
|
|
"* Description: %s\n"+
|
|
"* Explicit: %v\n"+
|
|
"* Privileged: %v\n"+
|
|
"* Photos: %v\n"+
|
|
"* Private: %v",
|
|
forum.Category,
|
|
forum.Title,
|
|
forum.Fragment,
|
|
forum.Description,
|
|
forum.Explicit,
|
|
forum.Privileged,
|
|
forum.PermitPhotos,
|
|
forum.Private,
|
|
))
|
|
|
|
return
|
|
} else {
|
|
session.FlashError(w, r, "Error creating the forum: %s", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get the list of moderators.
|
|
var mods []*models.User
|
|
if forum != nil {
|
|
mods, err = forum.GetModerators()
|
|
if err != nil {
|
|
session.FlashError(w, r, "Error getting moderators list: %s", err)
|
|
}
|
|
}
|
|
|
|
var vars = map[string]interface{}{
|
|
"EditID": editID,
|
|
"EditForum": forum,
|
|
"Categories": config.ForumCategories,
|
|
"Moderators": mods,
|
|
}
|
|
if err := tmpl.Execute(w, r, vars); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
})
|
|
}
|