@ -86,6 +86,7 @@ type Comment struct {
PosterID int64 ` xorm:"INDEX" `
PosterID int64 ` xorm:"INDEX" `
Poster * User ` xorm:"-" `
Poster * User ` xorm:"-" `
IssueID int64 ` xorm:"INDEX" `
IssueID int64 ` xorm:"INDEX" `
Issue * Issue ` xorm:"-" `
LabelID int64
LabelID int64
Label * Label ` xorm:"-" `
Label * Label ` xorm:"-" `
OldMilestoneID int64
OldMilestoneID int64
@ -116,6 +117,15 @@ type Comment struct {
ShowTag CommentTag ` xorm:"-" `
ShowTag CommentTag ` xorm:"-" `
}
}
// LoadIssue loads issue from database
func ( c * Comment ) LoadIssue ( ) ( err error ) {
if c . Issue != nil {
return nil
}
c . Issue , err = GetIssueByID ( c . IssueID )
return
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func ( c * Comment ) AfterLoad ( session * xorm . Session ) {
func ( c * Comment ) AfterLoad ( session * xorm . Session ) {
var err error
var err error
@ -146,40 +156,40 @@ func (c *Comment) AfterDelete() {
// HTMLURL formats a URL-string to the issue-comment
// HTMLURL formats a URL-string to the issue-comment
func ( c * Comment ) HTMLURL ( ) string {
func ( c * Comment ) HTMLURL ( ) string {
issue , err := GetIssueByID ( c . IssueID )
err := c . LoadIssue ( )
if err != nil { // Silently dropping errors :unamused:
if err != nil { // Silently dropping errors :unamused:
log . Error ( 4 , "GetIssueByID (%d): %v" , c . IssueID , err )
log . Error ( 4 , "LoadIssue (%d): %v" , c . IssueID , err )
return ""
return ""
}
}
return fmt . Sprintf ( "%s#%s" , i ssue. HTMLURL ( ) , c . HashTag ( ) )
return fmt . Sprintf ( "%s#%s" , c . I ssue. HTMLURL ( ) , c . HashTag ( ) )
}
}
// IssueURL formats a URL-string to the issue
// IssueURL formats a URL-string to the issue
func ( c * Comment ) IssueURL ( ) string {
func ( c * Comment ) IssueURL ( ) string {
issue , err := GetIssueByID ( c . IssueID )
err := c . LoadIssue ( )
if err != nil { // Silently dropping errors :unamused:
if err != nil { // Silently dropping errors :unamused:
log . Error ( 4 , "GetIssueByID (%d): %v" , c . IssueID , err )
log . Error ( 4 , "LoadIssue (%d): %v" , c . IssueID , err )
return ""
return ""
}
}
if i ssue. IsPull {
if c . I ssue. IsPull {
return ""
return ""
}
}
return i ssue. HTMLURL ( )
return c . I ssue. HTMLURL ( )
}
}
// PRURL formats a URL-string to the pull-request
// PRURL formats a URL-string to the pull-request
func ( c * Comment ) PRURL ( ) string {
func ( c * Comment ) PRURL ( ) string {
issue , err := GetIssueByID ( c . IssueID )
err := c . LoadIssue ( )
if err != nil { // Silently dropping errors :unamused:
if err != nil { // Silently dropping errors :unamused:
log . Error ( 4 , "GetIssueByID (%d): %v" , c . IssueID , err )
log . Error ( 4 , "LoadIssue (%d): %v" , c . IssueID , err )
return ""
return ""
}
}
if ! i ssue. IsPull {
if ! c . I ssue. IsPull {
return ""
return ""
}
}
return i ssue. HTMLURL ( )
return c . I ssue. HTMLURL ( )
}
}
// APIFormat converts a Comment to the api.Comment format
// APIFormat converts a Comment to the api.Comment format
@ -196,9 +206,14 @@ func (c *Comment) APIFormat() *api.Comment {
}
}
}
}
// CommentHashTag returns unique hash tag for comment id.
func CommentHashTag ( id int64 ) string {
return fmt . Sprintf ( "issuecomment-%d" , id )
}
// HashTag returns unique hash tag for comment.
// HashTag returns unique hash tag for comment.
func ( c * Comment ) HashTag ( ) string {
func ( c * Comment ) HashTag ( ) string {
return "issuecomment-" + com . ToStr ( c . ID )
return CommentHashTag ( c . ID )
}
}
// EventTag returns unique event hash tag for comment.
// EventTag returns unique event hash tag for comment.
@ -576,7 +591,7 @@ func CreateComment(opts *CreateCommentOptions) (comment *Comment, err error) {
// CreateIssueComment creates a plain issue comment.
// CreateIssueComment creates a plain issue comment.
func CreateIssueComment ( doer * User , repo * Repository , issue * Issue , content string , attachments [ ] string ) ( * Comment , error ) {
func CreateIssueComment ( doer * User , repo * Repository , issue * Issue , content string , attachments [ ] string ) ( * Comment , error ) {
return CreateComment ( & CreateCommentOptions {
comment , err := CreateComment ( & CreateCommentOptions {
Type : CommentTypeComment ,
Type : CommentTypeComment ,
Doer : doer ,
Doer : doer ,
Repo : repo ,
Repo : repo ,
@ -584,6 +599,21 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
Content : content ,
Content : content ,
Attachments : attachments ,
Attachments : attachments ,
} )
} )
if err != nil {
return nil , fmt . Errorf ( "CreateComment: %v" , err )
}
mode , _ := AccessLevel ( doer . ID , repo )
if err = PrepareWebhooks ( repo , HookEventIssueComment , & api . IssueCommentPayload {
Action : api . HookIssueCommentCreated ,
Issue : issue . APIFormat ( ) ,
Comment : comment . APIFormat ( ) ,
Repository : repo . APIFormat ( mode ) ,
Sender : doer . APIFormat ( ) ,
} ) ; err != nil {
log . Error ( 2 , "PrepareWebhooks [comment_id: %d]: %v" , comment . ID , err )
}
return comment , nil
}
}
// CreateRefComment creates a commit reference comment to issue.
// CreateRefComment creates a commit reference comment to issue.
@ -696,17 +726,41 @@ func GetCommentsByRepoIDSince(repoID, since int64) ([]*Comment, error) {
}
}
// UpdateComment updates information of comment.
// UpdateComment updates information of comment.
func UpdateComment ( c * Comment ) error {
func UpdateComment ( doer * User , c * Comment , oldContent string ) error {
if _ , err := x . ID ( c . ID ) . AllCols ( ) . Update ( c ) ; err != nil {
if _ , err := x . ID ( c . ID ) . AllCols ( ) . Update ( c ) ; err != nil {
return err
return err
} else if c . Type == CommentTypeComment {
} else if c . Type == CommentTypeComment {
UpdateIssueIndexer ( c . IssueID )
UpdateIssueIndexer ( c . IssueID )
}
}
if err := c . LoadIssue ( ) ; err != nil {
return err
}
if err := c . Issue . LoadAttributes ( ) ; err != nil {
return err
}
mode , _ := AccessLevel ( doer . ID , c . Issue . Repo )
if err := PrepareWebhooks ( c . Issue . Repo , HookEventIssueComment , & api . IssueCommentPayload {
Action : api . HookIssueCommentEdited ,
Issue : c . Issue . APIFormat ( ) ,
Comment : c . APIFormat ( ) ,
Changes : & api . ChangesPayload {
Body : & api . ChangesFromPayload {
From : oldContent ,
} ,
} ,
Repository : c . Issue . Repo . APIFormat ( mode ) ,
Sender : doer . APIFormat ( ) ,
} ) ; err != nil {
log . Error ( 2 , "PrepareWebhooks [comment_id: %d]: %v" , c . ID , err )
}
return nil
return nil
}
}
// DeleteComment deletes the comment
// DeleteComment deletes the comment
func DeleteComment ( comment * Comment ) error {
func DeleteComment ( doer * User , comment * Comment ) error {
sess := x . NewSession ( )
sess := x . NewSession ( )
defer sess . Close ( )
defer sess . Close ( )
if err := sess . Begin ( ) ; err != nil {
if err := sess . Begin ( ) ; err != nil {
@ -733,5 +787,25 @@ func DeleteComment(comment *Comment) error {
} else if comment . Type == CommentTypeComment {
} else if comment . Type == CommentTypeComment {
UpdateIssueIndexer ( comment . IssueID )
UpdateIssueIndexer ( comment . IssueID )
}
}
if err := comment . LoadIssue ( ) ; err != nil {
return err
}
if err := comment . Issue . LoadAttributes ( ) ; err != nil {
return err
}
mode , _ := AccessLevel ( doer . ID , comment . Issue . Repo )
if err := PrepareWebhooks ( comment . Issue . Repo , HookEventIssueComment , & api . IssueCommentPayload {
Action : api . HookIssueCommentDeleted ,
Issue : comment . Issue . APIFormat ( ) ,
Comment : comment . APIFormat ( ) ,
Repository : comment . Issue . Repo . APIFormat ( mode ) ,
Sender : doer . APIFormat ( ) ,
} ) ; err != nil {
log . Error ( 2 , "PrepareWebhooks [comment_id: %d]: %v" , comment . ID , err )
}
return nil
return nil
}
}