blog/src/controllers/contact/contact.go

105 lines
2.9 KiB
Go

package contact
import (
"fmt"
"html/template"
"net/http"
"os"
"path/filepath"
"time"
"github.com/gorilla/mux"
"github.com/kirsle/blog/src/forms"
"github.com/kirsle/blog/src/log"
"github.com/kirsle/blog/src/mail"
"github.com/kirsle/blog/src/markdown"
"github.com/kirsle/blog/src/render"
"github.com/kirsle/blog/src/responses"
"github.com/kirsle/blog/models/settings"
)
// Register attaches the contact URL to the app.
func Register(r *mux.Router) {
r.HandleFunc("/contact", func(w http.ResponseWriter, r *http.Request) {
// Allow ?next= to redirect to other local pages.
nextURL := r.FormValue("next")
if nextURL != "" && nextURL[0] != '/' {
log.Error("/contact?next=: URL must be a local page beginning with /")
nextURL = ""
}
form := &forms.Contact{}
v := map[string]interface{}{
"Form": form,
}
// If there is no site admin, show an error.
cfg, err := settings.Load()
if err != nil {
responses.Error(w, r, "Error loading site configuration!")
return
} else if cfg.Site.AdminEmail == "" {
responses.Error(w, r, "There is no admin email configured for this website!")
return
} else if !cfg.Mail.Enabled {
responses.Error(w, r, "This website doesn't have an e-mail gateway configured.")
return
}
// Posting?
if r.Method == http.MethodPost {
form.ParseForm(r)
if err = form.Validate(); err != nil {
// If they're not from the /contact front-end, redirect them
// with the flash.
if len(nextURL) > 0 {
responses.FlashAndRedirect(w, r, nextURL, err.Error())
return
}
// Otherwise flash and let the /contact page render to retain
// their form fields so far.
responses.Flash(w, r, err.Error())
} else {
go mail.SendEmail(mail.Email{
To: cfg.Site.AdminEmail,
Admin: true,
ReplyTo: form.Email,
Subject: fmt.Sprintf("Contact Form on %s: %s", cfg.Site.Title, form.Subject),
Template: ".email/contact.gohtml",
Data: map[string]interface{}{
"Name": form.Name,
"Message": template.HTML(markdown.RenderMarkdown(form.Message)),
"Email": form.Email,
},
})
// Log it to disk, too.
fh, err := os.OpenFile(filepath.Join(*render.UserRoot, ".contact.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
responses.Flash(w, r, "Error logging the message to disk: %s", err)
} else {
fh.WriteString(fmt.Sprintf(
"Date: %s\nName: %s\nEmail: %s\nSubject: %s\n\n%s\n\n--------------------\n\n",
time.Now().Format(time.UnixDate),
form.Name,
form.Email,
form.Subject,
form.Message,
))
fh.Close()
}
if len(nextURL) > 0 {
responses.FlashAndRedirect(w, r, nextURL, "Your message has been sent.")
} else {
responses.FlashAndRedirect(w, r, "/contact", "Your message has been sent.")
}
return
}
}
render.Template(w, r, "contact", v)
})
}