本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.0KB

  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "fmt"
  7. "xorm.io/xorm"
  8. )
  9. // IssueAssignees saves all issue assignees
  10. type IssueAssignees struct {
  11. ID int64 `xorm:"pk autoincr"`
  12. AssigneeID int64 `xorm:"INDEX"`
  13. IssueID int64 `xorm:"INDEX"`
  14. }
  15. // This loads all assignees of an issue
  16. func (issue *Issue) loadAssignees(e Engine) (err error) {
  17. // Reset maybe preexisting assignees
  18. issue.Assignees = []*User{}
  19. err = e.Table("`user`").
  20. Join("INNER", "issue_assignees", "assignee_id = `user`.id").
  21. Where("issue_assignees.issue_id = ?", issue.ID).
  22. Find(&issue.Assignees)
  23. if err != nil {
  24. return err
  25. }
  26. // Check if we have at least one assignee and if yes put it in as `Assignee`
  27. if len(issue.Assignees) > 0 {
  28. issue.Assignee = issue.Assignees[0]
  29. }
  30. return
  31. }
  32. // GetAssigneesByIssue returns everyone assigned to that issue
  33. func GetAssigneesByIssue(issue *Issue) (assignees []*User, err error) {
  34. return getAssigneesByIssue(x, issue)
  35. }
  36. func getAssigneesByIssue(e Engine, issue *Issue) (assignees []*User, err error) {
  37. err = issue.loadAssignees(e)
  38. if err != nil {
  39. return assignees, err
  40. }
  41. return issue.Assignees, nil
  42. }
  43. // IsUserAssignedToIssue returns true when the user is assigned to the issue
  44. func IsUserAssignedToIssue(issue *Issue, user *User) (isAssigned bool, err error) {
  45. return isUserAssignedToIssue(x, issue, user)
  46. }
  47. func isUserAssignedToIssue(e Engine, issue *Issue, user *User) (isAssigned bool, err error) {
  48. return e.Get(&IssueAssignees{IssueID: issue.ID, AssigneeID: user.ID})
  49. }
  50. // MakeAssigneeList concats a string with all names of the assignees. Useful for logs.
  51. func MakeAssigneeList(issue *Issue) (assigneeList string, err error) {
  52. err = issue.loadAssignees(x)
  53. if err != nil {
  54. return "", err
  55. }
  56. for in, assignee := range issue.Assignees {
  57. assigneeList += assignee.Name
  58. if len(issue.Assignees) > (in + 1) {
  59. assigneeList += ", "
  60. }
  61. }
  62. return
  63. }
  64. // ClearAssigneeByUserID deletes all assignments of an user
  65. func clearAssigneeByUserID(sess *xorm.Session, userID int64) (err error) {
  66. _, err = sess.Delete(&IssueAssignees{AssigneeID: userID})
  67. return
  68. }
  69. // ToggleAssignee changes a user between assigned and not assigned for this issue, and make issue comment for it.
  70. func (issue *Issue) ToggleAssignee(doer *User, assigneeID int64) (removed bool, comment *Comment, err error) {
  71. sess := x.NewSession()
  72. defer sess.Close()
  73. if err := sess.Begin(); err != nil {
  74. return false, nil, err
  75. }
  76. removed, comment, err = issue.toggleAssignee(sess, doer, assigneeID, false)
  77. if err != nil {
  78. return false, nil, err
  79. }
  80. if err := sess.Commit(); err != nil {
  81. return false, nil, err
  82. }
  83. return removed, comment, nil
  84. }
  85. func (issue *Issue) toggleAssignee(sess *xorm.Session, doer *User, assigneeID int64, isCreate bool) (removed bool, comment *Comment, err error) {
  86. removed, err = toggleUserAssignee(sess, issue, assigneeID)
  87. if err != nil {
  88. return false, nil, fmt.Errorf("UpdateIssueUserByAssignee: %v", err)
  89. }
  90. // Repo infos
  91. if err = issue.loadRepo(sess); err != nil {
  92. return false, nil, fmt.Errorf("loadRepo: %v", err)
  93. }
  94. // Comment
  95. comment, err = createAssigneeComment(sess, doer, issue.Repo, issue, assigneeID, removed)
  96. if err != nil {
  97. return false, nil, fmt.Errorf("createAssigneeComment: %v", err)
  98. }
  99. // if pull request is in the middle of creation - don't call webhook
  100. if isCreate {
  101. return removed, comment, err
  102. }
  103. return removed, comment, nil
  104. }
  105. // toggles user assignee state in database
  106. func toggleUserAssignee(e *xorm.Session, issue *Issue, assigneeID int64) (removed bool, err error) {
  107. // Check if the user exists
  108. assignee, err := getUserByID(e, assigneeID)
  109. if err != nil {
  110. return false, err
  111. }
  112. // Check if the submitted user is already assigned, if yes delete him otherwise add him
  113. var i int
  114. for i = 0; i < len(issue.Assignees); i++ {
  115. if issue.Assignees[i].ID == assigneeID {
  116. break
  117. }
  118. }
  119. assigneeIn := IssueAssignees{AssigneeID: assigneeID, IssueID: issue.ID}
  120. toBeDeleted := i < len(issue.Assignees)
  121. if toBeDeleted {
  122. issue.Assignees = append(issue.Assignees[:i], issue.Assignees[i:]...)
  123. _, err = e.Delete(assigneeIn)
  124. if err != nil {
  125. return toBeDeleted, err
  126. }
  127. } else {
  128. issue.Assignees = append(issue.Assignees, assignee)
  129. _, err = e.Insert(assigneeIn)
  130. if err != nil {
  131. return toBeDeleted, err
  132. }
  133. }
  134. return toBeDeleted, nil
  135. }
  136. // MakeIDsFromAPIAssigneesToAdd returns an array with all assignee IDs
  137. func MakeIDsFromAPIAssigneesToAdd(oneAssignee string, multipleAssignees []string) (assigneeIDs []int64, err error) {
  138. // Keeping the old assigning method for compatibility reasons
  139. if oneAssignee != "" {
  140. // Prevent double adding assignees
  141. var isDouble bool
  142. for _, assignee := range multipleAssignees {
  143. if assignee == oneAssignee {
  144. isDouble = true
  145. break
  146. }
  147. }
  148. if !isDouble {
  149. multipleAssignees = append(multipleAssignees, oneAssignee)
  150. }
  151. }
  152. // Get the IDs of all assignees
  153. assigneeIDs, err = GetUserIDsByNames(multipleAssignees, false)
  154. return
  155. }
上海开阖软件有限公司 沪ICP备12045867号-1