Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package issue
  4. import (
  5. "context"
  6. "fmt"
  7. "code.gitea.io/gitea/models/db"
  8. issues_model "code.gitea.io/gitea/models/issues"
  9. access_model "code.gitea.io/gitea/models/perm/access"
  10. repo_model "code.gitea.io/gitea/models/repo"
  11. user_model "code.gitea.io/gitea/models/user"
  12. "code.gitea.io/gitea/modules/timeutil"
  13. notify_service "code.gitea.io/gitea/services/notify"
  14. )
  15. // CreateRefComment creates a commit reference comment to issue.
  16. func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error {
  17. if len(commitSHA) == 0 {
  18. return fmt.Errorf("cannot create reference with empty commit SHA")
  19. }
  20. if user_model.IsUserBlockedBy(ctx, doer, issue.PosterID, repo.OwnerID) {
  21. if isAdmin, _ := access_model.IsUserRepoAdmin(ctx, repo, doer); !isAdmin {
  22. return user_model.ErrBlockedUser
  23. }
  24. }
  25. // Check if same reference from same commit has already existed.
  26. has, err := db.GetEngine(ctx).Get(&issues_model.Comment{
  27. Type: issues_model.CommentTypeCommitRef,
  28. IssueID: issue.ID,
  29. CommitSHA: commitSHA,
  30. })
  31. if err != nil {
  32. return fmt.Errorf("check reference comment: %w", err)
  33. } else if has {
  34. return nil
  35. }
  36. _, err = issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
  37. Type: issues_model.CommentTypeCommitRef,
  38. Doer: doer,
  39. Repo: repo,
  40. Issue: issue,
  41. CommitSHA: commitSHA,
  42. Content: content,
  43. })
  44. return err
  45. }
  46. // CreateIssueComment creates a plain issue comment.
  47. func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content string, attachments []string) (*issues_model.Comment, error) {
  48. if user_model.IsUserBlockedBy(ctx, doer, issue.PosterID, repo.OwnerID) {
  49. if isAdmin, _ := access_model.IsUserRepoAdmin(ctx, repo, doer); !isAdmin {
  50. return nil, user_model.ErrBlockedUser
  51. }
  52. }
  53. comment, err := issues_model.CreateComment(ctx, &issues_model.CreateCommentOptions{
  54. Type: issues_model.CommentTypeComment,
  55. Doer: doer,
  56. Repo: repo,
  57. Issue: issue,
  58. Content: content,
  59. Attachments: attachments,
  60. })
  61. if err != nil {
  62. return nil, err
  63. }
  64. mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content)
  65. if err != nil {
  66. return nil, err
  67. }
  68. notify_service.CreateIssueComment(ctx, doer, repo, issue, comment, mentions)
  69. return comment, nil
  70. }
  71. // UpdateComment updates information of comment.
  72. func UpdateComment(ctx context.Context, c *issues_model.Comment, doer *user_model.User, oldContent string) error {
  73. if err := c.LoadIssue(ctx); err != nil {
  74. return err
  75. }
  76. if err := c.Issue.LoadRepo(ctx); err != nil {
  77. return err
  78. }
  79. if user_model.IsUserBlockedBy(ctx, doer, c.Issue.PosterID, c.Issue.Repo.OwnerID) {
  80. if isAdmin, _ := access_model.IsUserRepoAdmin(ctx, c.Issue.Repo, doer); !isAdmin {
  81. return user_model.ErrBlockedUser
  82. }
  83. }
  84. needsContentHistory := c.Content != oldContent && c.Type.HasContentSupport()
  85. if needsContentHistory {
  86. hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, c.IssueID, c.ID)
  87. if err != nil {
  88. return err
  89. }
  90. if !hasContentHistory {
  91. if err = issues_model.SaveIssueContentHistory(ctx, c.PosterID, c.IssueID, c.ID,
  92. c.CreatedUnix, oldContent, true); err != nil {
  93. return err
  94. }
  95. }
  96. }
  97. if err := issues_model.UpdateComment(ctx, c, doer); err != nil {
  98. return err
  99. }
  100. if needsContentHistory {
  101. err := issues_model.SaveIssueContentHistory(ctx, doer.ID, c.IssueID, c.ID, timeutil.TimeStampNow(), c.Content, false)
  102. if err != nil {
  103. return err
  104. }
  105. }
  106. notify_service.UpdateComment(ctx, doer, c, oldContent)
  107. return nil
  108. }
  109. // DeleteComment deletes the comment
  110. func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_model.Comment) error {
  111. err := db.WithTx(ctx, func(ctx context.Context) error {
  112. return issues_model.DeleteComment(ctx, comment)
  113. })
  114. if err != nil {
  115. return err
  116. }
  117. notify_service.DeleteComment(ctx, doer, comment)
  118. return nil
  119. }