@@ -83,9 +83,10 @@ const (
8383type Comment struct {
8484 ID int64 `xorm:"pk autoincr"`
8585 Type CommentType
86- PosterID int64 `xorm:"INDEX"`
87- Poster * User `xorm:"-"`
88- IssueID int64 `xorm:"INDEX"`
86+ PosterID int64 `xorm:"INDEX"`
87+ Poster * User `xorm:"-"`
88+ IssueID int64 `xorm:"INDEX"`
89+ Issue * Issue `xorm:"-"`
8990 LabelID int64
9091 Label * Label `xorm:"-"`
9192 OldMilestoneID int64
@@ -116,6 +117,15 @@ type Comment struct {
116117 ShowTag CommentTag `xorm:"-"`
117118}
118119
120+ // LoadIssue loads issue from database
121+ func (c * Comment ) LoadIssue () (err error ) {
122+ if c .Issue != nil {
123+ return nil
124+ }
125+ c .Issue , err = GetIssueByID (c .IssueID )
126+ return
127+ }
128+
119129// AfterLoad is invoked from XORM after setting the values of all fields of this object.
120130func (c * Comment ) AfterLoad (session * xorm.Session ) {
121131 var err error
@@ -146,40 +156,40 @@ func (c *Comment) AfterDelete() {
146156
147157// HTMLURL formats a URL-string to the issue-comment
148158func (c * Comment ) HTMLURL () string {
149- issue , err := GetIssueByID ( c . IssueID )
159+ err := c . LoadIssue ( )
150160 if err != nil { // Silently dropping errors :unamused:
151- log .Error (4 , "GetIssueByID (%d): %v" , c .IssueID , err )
161+ log .Error (4 , "LoadIssue (%d): %v" , c .IssueID , err )
152162 return ""
153163 }
154- return fmt .Sprintf ("%s#%s" , issue .HTMLURL (), c .HashTag ())
164+ return fmt .Sprintf ("%s#%s" , c . Issue .HTMLURL (), c .HashTag ())
155165}
156166
157167// IssueURL formats a URL-string to the issue
158168func (c * Comment ) IssueURL () string {
159- issue , err := GetIssueByID ( c . IssueID )
169+ err := c . LoadIssue ( )
160170 if err != nil { // Silently dropping errors :unamused:
161- log .Error (4 , "GetIssueByID (%d): %v" , c .IssueID , err )
171+ log .Error (4 , "LoadIssue (%d): %v" , c .IssueID , err )
162172 return ""
163173 }
164174
165- if issue .IsPull {
175+ if c . Issue .IsPull {
166176 return ""
167177 }
168- return issue .HTMLURL ()
178+ return c . Issue .HTMLURL ()
169179}
170180
171181// PRURL formats a URL-string to the pull-request
172182func (c * Comment ) PRURL () string {
173- issue , err := GetIssueByID ( c . IssueID )
183+ err := c . LoadIssue ( )
174184 if err != nil { // Silently dropping errors :unamused:
175- log .Error (4 , "GetIssueByID (%d): %v" , c .IssueID , err )
185+ log .Error (4 , "LoadIssue (%d): %v" , c .IssueID , err )
176186 return ""
177187 }
178188
179- if ! issue .IsPull {
189+ if ! c . Issue .IsPull {
180190 return ""
181191 }
182- return issue .HTMLURL ()
192+ return c . Issue .HTMLURL ()
183193}
184194
185195// APIFormat converts a Comment to the api.Comment format
@@ -196,9 +206,14 @@ func (c *Comment) APIFormat() *api.Comment {
196206 }
197207}
198208
209+ // CommentHashTag returns unique hash tag for comment id.
210+ func CommentHashTag (id int64 ) string {
211+ return fmt .Sprintf ("issuecomment-%d" , id )
212+ }
213+
199214// HashTag returns unique hash tag for comment.
200215func (c * Comment ) HashTag () string {
201- return "issuecomment-" + com . ToStr (c .ID )
216+ return CommentHashTag (c .ID )
202217}
203218
204219// EventTag returns unique event hash tag for comment.
@@ -576,14 +591,29 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
576591
577592// CreateIssueComment creates a plain issue comment.
578593func CreateIssueComment (doer * User , repo * Repository , issue * Issue , content string , attachments []string ) (* Comment , error ) {
579- return CreateComment (& CreateCommentOptions {
594+ comment , err := CreateComment (& CreateCommentOptions {
580595 Type : CommentTypeComment ,
581596 Doer : doer ,
582597 Repo : repo ,
583598 Issue : issue ,
584599 Content : content ,
585600 Attachments : attachments ,
586601 })
602+ if err != nil {
603+ return nil , fmt .Errorf ("CreateComment: %v" , err )
604+ }
605+
606+ mode , _ := AccessLevel (doer .ID , repo )
607+ if err = PrepareWebhooks (repo , HookEventIssueComment , & api.IssueCommentPayload {
608+ Action : api .HookIssueCommentCreated ,
609+ Issue : issue .APIFormat (),
610+ Comment : comment .APIFormat (),
611+ Repository : repo .APIFormat (mode ),
612+ Sender : doer .APIFormat (),
613+ }); err != nil {
614+ log .Error (2 , "PrepareWebhooks [comment_id: %d]: %v" , comment .ID , err )
615+ }
616+ return comment , nil
587617}
588618
589619// CreateRefComment creates a commit reference comment to issue.
@@ -696,17 +726,41 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
696726}
697727
698728// UpdateComment updates information of comment.
699- func UpdateComment (c * Comment ) error {
729+ func UpdateComment (doer * User , c * Comment , oldContent string ) error {
700730 if _ , err := x .ID (c .ID ).AllCols ().Update (c ); err != nil {
701731 return err
702732 } else if c .Type == CommentTypeComment {
703733 UpdateIssueIndexer (c .IssueID )
704734 }
735+
736+ if err := c .LoadIssue (); err != nil {
737+ return err
738+ }
739+ if err := c .Issue .LoadAttributes (); err != nil {
740+ return err
741+ }
742+
743+ mode , _ := AccessLevel (doer .ID , c .Issue .Repo )
744+ if err := PrepareWebhooks (c .Issue .Repo , HookEventIssueComment , & api.IssueCommentPayload {
745+ Action : api .HookIssueCommentEdited ,
746+ Issue : c .Issue .APIFormat (),
747+ Comment : c .APIFormat (),
748+ Changes : & api.ChangesPayload {
749+ Body : & api.ChangesFromPayload {
750+ From : oldContent ,
751+ },
752+ },
753+ Repository : c .Issue .Repo .APIFormat (mode ),
754+ Sender : doer .APIFormat (),
755+ }); err != nil {
756+ log .Error (2 , "PrepareWebhooks [comment_id: %d]: %v" , c .ID , err )
757+ }
758+
705759 return nil
706760}
707761
708762// DeleteComment deletes the comment
709- func DeleteComment (comment * Comment ) error {
763+ func DeleteComment (doer * User , comment * Comment ) error {
710764 sess := x .NewSession ()
711765 defer sess .Close ()
712766 if err := sess .Begin (); err != nil {
@@ -733,5 +787,25 @@ func DeleteComment(comment *Comment) error {
733787 } else if comment .Type == CommentTypeComment {
734788 UpdateIssueIndexer (comment .IssueID )
735789 }
790+
791+ if err := comment .LoadIssue (); err != nil {
792+ return err
793+ }
794+ if err := comment .Issue .LoadAttributes (); err != nil {
795+ return err
796+ }
797+
798+ mode , _ := AccessLevel (doer .ID , comment .Issue .Repo )
799+
800+ if err := PrepareWebhooks (comment .Issue .Repo , HookEventIssueComment , & api.IssueCommentPayload {
801+ Action : api .HookIssueCommentDeleted ,
802+ Issue : comment .Issue .APIFormat (),
803+ Comment : comment .APIFormat (),
804+ Repository : comment .Issue .Repo .APIFormat (mode ),
805+ Sender : doer .APIFormat (),
806+ }); err != nil {
807+ log .Error (2 , "PrepareWebhooks [comment_id: %d]: %v" , comment .ID , err )
808+ }
809+
736810 return nil
737811}
0 commit comments