1cc2306cbf
* Add the PollVotes table and associated logic. * Multiple choice polls supported. * Expiring and non-expiring polls. * Icons and badges on the forum pages to show posts with polls * Bugfix: non-explicit users getting SQL errors on Newest Posts page.
92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package poll
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/models"
|
|
"code.nonshy.com/nonshy/website/pkg/session"
|
|
"code.nonshy.com/nonshy/website/pkg/templates"
|
|
)
|
|
|
|
// Vote controller for polls.
|
|
func Vote() http.HandlerFunc {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
// Form parameters
|
|
pollID uint64
|
|
fromThreadID uint64
|
|
answers = r.Form["answer"] // a slice in case of MultipleChoice
|
|
nextURL string
|
|
)
|
|
|
|
// Parse integer params.
|
|
if value, err := strconv.Atoi(r.FormValue("poll_id")); err != nil {
|
|
session.FlashError(w, r, "Invalid poll ID")
|
|
templates.Redirect(w, "/")
|
|
return
|
|
} else {
|
|
pollID = uint64(value)
|
|
}
|
|
|
|
// Currently polls only exist in forum threads, require the thread ID.
|
|
if value, err := strconv.Atoi(r.FormValue("from_thread_id")); err != nil {
|
|
session.FlashError(w, r, "Invalid thread ID")
|
|
templates.Redirect(w, "/")
|
|
return
|
|
} else {
|
|
fromThreadID = uint64(value)
|
|
nextURL = fmt.Sprintf("/forum/thread/%d", fromThreadID)
|
|
}
|
|
|
|
// POST request only.
|
|
if r.Method != http.MethodPost {
|
|
session.FlashError(w, r, "POST requests only.")
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
// An answer is required.
|
|
if len(answers) == 0 || len(answers) == 1 && answers[0] == "" {
|
|
session.FlashError(w, r, "An answer to this poll is required for voting.")
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
// Get the current user.
|
|
user, err := session.CurrentUser(r)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Unexpected error: couldn't get CurrentUser")
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
// Look up the poll.
|
|
poll, err := models.GetPoll(pollID)
|
|
if err != nil {
|
|
session.FlashError(w, r, "Poll not found.")
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
// Is it accepting responses?
|
|
result := poll.Result(user)
|
|
if !result.AcceptingVotes {
|
|
session.FlashError(w, r, "This poll is not accepting your vote at this time.")
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
// Cast the vote!
|
|
if err := poll.CastVote(user, answers); err != nil {
|
|
session.FlashError(w, r, "Couldn't cast the vote: %s", err)
|
|
templates.Redirect(w, nextURL)
|
|
return
|
|
}
|
|
|
|
session.Flash(w, r, "Your vote has been recorded!")
|
|
templates.Redirect(w, nextURL)
|
|
})
|
|
}
|