package forum import ( "net/http" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/models" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" ) // Search the forums. func Search() http.HandlerFunc { tmpl := templates.Must("forum/search.html") // Whitelist for ordering options. var sortWhitelist = []string{ "created_at desc", "created_at asc", } return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ( searchTerm = r.FormValue("q") byUsername = r.FormValue("username") postType = r.FormValue("type") inForum = r.FormValue("in") categories = []string{} sort = r.FormValue("sort") sortOK bool ) // Sort options. for _, v := range sortWhitelist { if sort == v { sortOK = true break } } if !sortOK { sort = sortWhitelist[0] } // All comments, or threads only? if postType != "threads" { postType = "all" } // In forums switch inForum { case "official": categories = config.ForumCategories case "community": categories = []string{""} } // 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 } // Filters: find the user ID. var filterUserID uint64 if byUsername != "" { user, err := models.FindUser(byUsername) if err != nil { session.FlashError(w, r, "Couldn't search posts by that username: no such username found.") templates.Redirect(w, r.URL.Path) return } filterUserID = user.ID } // Parse their search term. var ( search = models.ParseSearchString(searchTerm) filters = models.ForumSearchFilters{ UserID: filterUserID, ThreadsOnly: postType == "threads", } pager = &models.Pagination{ Page: 1, PerPage: config.PageSizeThreadList, Sort: sort, } ) pager.ParsePage(r) posts, err := models.SearchForum(currentUser, categories, search, filters, pager) if err != nil { session.FlashError(w, r, "Couldn't search the forums: %s", err) templates.Redirect(w, "/") return } // Map the originating threads to each comment. threadMap, err := models.MapForumCommentThreads(posts) if err != nil { log.Error("Couldn't map forum threads to comments: %s", err) } // Get any photo attachments for these comments. photos, err := models.MapCommentPhotos(posts) if err != nil { log.Error("Couldn't MapCommentPhotos: %s", err) } var vars = map[string]interface{}{ "CurrentForumTab": "search", "Pager": pager, "Comments": posts, "ThreadMap": threadMap, "PhotoMap": photos, "SearchTerm": searchTerm, "ByUsername": byUsername, "Type": postType, "InForum": inForum, "Sort": sort, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }