github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/web/post/save.go (about) 1 package webpost 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/gosimple/slug" 8 "github.com/ngocphuongnb/tetua/app/config" 9 "github.com/ngocphuongnb/tetua/app/entities" 10 "github.com/ngocphuongnb/tetua/app/repositories" 11 "github.com/ngocphuongnb/tetua/app/server" 12 "github.com/ngocphuongnb/tetua/app/services" 13 "github.com/ngocphuongnb/tetua/app/utils" 14 ) 15 16 func postMutationToPost(postData *entities.PostMutation) *entities.Post { 17 return &entities.Post{ 18 Name: postData.Name, 19 Slug: slug.Make(postData.Name), 20 Content: postData.Content, 21 ContentHTML: postData.ContentHTML, 22 Description: postData.Description, 23 FeaturedImageID: postData.FeaturedImageID, 24 Draft: postData.Draft, 25 TopicIDs: postData.TopicIDs, 26 } 27 } 28 29 func Save(c server.Context) (err error) { 30 var post *entities.Post 31 featuredImage := &entities.File{} 32 postData := getPostSaveData(c) 33 contentHtml, err := utils.MarkdownToHtml(postData.Content) 34 35 if err != nil { 36 c.WithError("Error convert markdown to html", err) 37 } 38 39 if post = c.Post(); post != nil { 40 postData.Slug = post.Slug 41 postData.Description = post.Description 42 } 43 44 if postData.FeaturedImageID > 0 { 45 if featuredImage, err = repositories.File.ByID(c.Context(), postData.FeaturedImageID); err != nil { 46 c.WithError("Error getting featured image", err) 47 } 48 } 49 50 if !c.Messages().HasError() { 51 var savedPost *entities.Post 52 postData.Slug = slug.Make(postData.Name) 53 postData.ContentHTML = contentHtml 54 savePostData := postMutationToPost(postData) 55 user := c.User() 56 57 if post := c.Post(); post != nil { 58 now := time.Now() 59 savePostData.ID = post.ID 60 savePostData.Approved = post.Approved 61 savePostData.UpdatedAt = &now 62 savedPost, err = repositories.Post.Update(c.Context(), savePostData) 63 } else { 64 savePostData.UserID = user.ID 65 savePostData.Approved = user.IsRoot() || config.Setting("auto_approve_post") == "yes" 66 savedPost, err = repositories.Post.Create(c.Context(), savePostData) 67 } 68 69 if err != nil { 70 c.Logger().Error("Error creating post", err) 71 c.Messages().AppendError("Error saving post") 72 return getComposeView(c, postData, featuredImage) 73 } 74 75 return c.RedirectToRoute("post.compose", entities.Map{"id": savedPost.ID}) 76 } 77 78 return getComposeView(c, postData, featuredImage) 79 } 80 81 func getPostSaveData(c server.Context) *entities.PostMutation { 82 var err error 83 postData := &entities.PostMutation{} 84 if err := c.BodyParser(postData); err != nil { 85 c.Logger().Error("Error parsing body", err) 86 c.Messages().AppendError("Bad request") 87 return postData 88 } 89 90 postData.Content = utils.SanitizeMarkdown(postData.Content) 91 lines := strings.Split(postData.Content, "\n") 92 postData.Name = utils.SanitizePlainText(strings.Trim(strings.Trim(lines[0], "#"), " ")) 93 postData.Content = strings.Join(lines[1:], "\n") 94 95 if postData.Name, err = utils.MarkdownToHtml(postData.Name); err != nil { 96 c.WithError("Error convert markdown to html", err) 97 postData.Name = "" 98 } else { 99 postData.Name = utils.SanitizePlainText(postData.Name) 100 postData.Name = strings.ReplaceAll(postData.Name, "\n", "") 101 postData.Name = strings.ReplaceAll(postData.Name, "\r", "") 102 postData.Name = strings.ReplaceAll(postData.Name, "\t", "") 103 } 104 105 if featuredImage, err := services.SaveFile(c, "featured_image"); err != nil { 106 c.WithError("Error saving featured image", err) 107 } else if featuredImage != nil { 108 postData.FeaturedImageID = featuredImage.ID 109 } 110 111 if postData.Name == "" || len(postData.Name) > 250 { 112 c.Messages().AppendError("Name is required and can't be more than 250 characters") 113 } 114 115 if postData.Content == "" { 116 c.Messages().AppendError("Content is required") 117 } 118 119 if len(postData.TopicIDs) == 0 { 120 c.Messages().AppendError("Topic is required") 121 } 122 123 return postData 124 }