func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { issue := &models.Issue{ RepoID: ctx.Repo.Repository.ID, Name: form.Title, PosterID: ctx.User.Id, Poster: ctx.User, Content: form.Body, } if ctx.Repo.IsWriter() { if len(form.Assignee) > 0 { assignee, err := models.GetUserByName(form.Assignee) if err != nil { if models.IsErrUserNotExist(err) { ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", form.Assignee)) } else { ctx.Error(500, "GetUserByName", err) } return } issue.AssigneeID = assignee.Id } issue.MilestoneID = form.Milestone } else { form.Labels = nil } if err := models.NewIssue(ctx.Repo.Repository, issue, form.Labels, nil); err != nil { ctx.Error(500, "NewIssue", err) return } else if err := repo.MailWatchersAndMentions(ctx.Context, issue); err != nil { ctx.Error(500, "MailWatchersAndMentions", err) return } if form.Closed { if err := issue.ChangeStatus(ctx.User, ctx.Repo.Repository, true); err != nil { ctx.Error(500, "issue.ChangeStatus", err) return } } // Refetch from database to assign some automatic values var err error issue, err = models.GetIssueByID(issue.ID) if err != nil { ctx.Error(500, "GetIssueByID", err) return } ctx.JSON(201, convert.ToIssue(issue)) }
func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.Status(404) } else { ctx.Error(500, "GetIssueByIndex", err) } return } if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.IsWriter() { ctx.Status(403) return } if len(form.Title) > 0 { issue.Title = form.Title } if form.Body != nil { issue.Content = *form.Body } if ctx.Repo.IsWriter() && form.Assignee != nil && (issue.Assignee == nil || issue.Assignee.LowerName != strings.ToLower(*form.Assignee)) { if len(*form.Assignee) == 0 { issue.AssigneeID = 0 } else { assignee, err := models.GetUserByName(*form.Assignee) if err != nil { if models.IsErrUserNotExist(err) { ctx.Error(422, "", fmt.Sprintf("assignee does not exist: [name: %s]", *form.Assignee)) } else { ctx.Error(500, "GetUserByName", err) } return } issue.AssigneeID = assignee.ID } if err = models.UpdateIssueUserByAssignee(issue); err != nil { ctx.Error(500, "UpdateIssueUserByAssignee", err) return } } if ctx.Repo.IsWriter() && form.Milestone != nil && issue.MilestoneID != *form.Milestone { oldMilestoneID := issue.MilestoneID issue.MilestoneID = *form.Milestone if err = models.ChangeMilestoneAssign(issue, oldMilestoneID); err != nil { ctx.Error(500, "ChangeMilestoneAssign", err) return } } if err = models.UpdateIssue(issue); err != nil { ctx.Error(500, "UpdateIssue", err) return } if form.State != nil { if err = issue.ChangeStatus(ctx.User, ctx.Repo.Repository, api.STATE_CLOSED == api.StateType(*form.State)); err != nil { ctx.Error(500, "ChangeStatus", err) return } } // Refetch from database to assign some automatic values issue, err = models.GetIssueByID(issue.ID) if err != nil { ctx.Error(500, "GetIssueByID", err) return } ctx.JSON(201, issue.APIFormat()) }
func Issues(ctx *middleware.Context) { ctx.Data["Title"] = ctx.Tr("issues") ctx.Data["PageIsDashboard"] = true ctx.Data["PageIsIssues"] = true viewType := ctx.Query("type") types := []string{"assigned", "created_by"} if !com.IsSliceContainsStr(types, viewType) { viewType = "all" } isShowClosed := ctx.Query("state") == "closed" var filterMode int switch viewType { case "assigned": filterMode = models.FM_ASSIGN case "created_by": filterMode = models.FM_CREATE } repoId, _ := com.StrTo(ctx.Query("repoid")).Int64() issueStats := models.GetUserIssueStats(ctx.User.Id, filterMode) // Get all repositories. repos, err := models.GetRepositories(ctx.User.Id, true) if err != nil { ctx.Handle(500, "user.Issues(GetRepositories)", err) return } repoIds := make([]int64, 0, len(repos)) showRepos := make([]*models.Repository, 0, len(repos)) for _, repo := range repos { if repo.NumIssues == 0 { continue } repoIds = append(repoIds, repo.ID) repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues issueStats.AllCount += int64(repo.NumOpenIssues) if isShowClosed { if repo.NumClosedIssues > 0 { if filterMode == models.FM_CREATE { repo.NumClosedIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed)) } showRepos = append(showRepos, repo) } } else { if repo.NumOpenIssues > 0 { if filterMode == models.FM_CREATE { repo.NumOpenIssues = int(models.GetIssueCountByPoster(ctx.User.Id, repo.ID, isShowClosed)) } showRepos = append(showRepos, repo) } } } if repoId > 0 { repoIds = []int64{repoId} } page, _ := com.StrTo(ctx.Query("page")).Int() // Get all issues. var ius []*models.IssueUser switch viewType { case "assigned": fallthrough case "created_by": ius, err = models.GetIssueUserPairsByMode(ctx.User.Id, repoId, isShowClosed, page, filterMode) default: ius, err = models.GetIssueUserPairsByRepoIds(repoIds, isShowClosed, page) } if err != nil { ctx.Handle(500, "user.Issues(GetAllIssueUserPairs)", err) return } issues := make([]*models.Issue, len(ius)) for i := range ius { issues[i], err = models.GetIssueByID(ius[i].IssueID) if err != nil { if models.IsErrIssueNotExist(err) { log.Warn("user.Issues(GetIssueById #%d): issue not exist", ius[i].IssueID) continue } else { ctx.Handle(500, fmt.Sprintf("user.Issues(GetIssueById #%d)", ius[i].IssueID), err) return } } issues[i].Repo, err = models.GetRepositoryByID(issues[i].RepoID) if err != nil { if models.IsErrRepoNotExist(err) { log.Warn("GetRepositoryById[%d]: repository not exist", issues[i].RepoID) continue } else { ctx.Handle(500, fmt.Sprintf("GetRepositoryById[%d]", issues[i].RepoID), err) return } } if err = issues[i].Repo.GetOwner(); err != nil { ctx.Handle(500, "user.Issues(GetOwner)", err) return } if err = issues[i].GetPoster(); err != nil { ctx.Handle(500, "user.Issues(GetUserById)", err) return } } ctx.Data["RepoId"] = repoId ctx.Data["Repos"] = showRepos ctx.Data["Issues"] = issues ctx.Data["ViewType"] = viewType ctx.Data["IssueStats"] = issueStats ctx.Data["IsShowClosed"] = isShowClosed if isShowClosed { ctx.Data["State"] = "closed" ctx.Data["ShowCount"] = issueStats.ClosedCount } else { ctx.Data["ShowCount"] = issueStats.OpenCount } ctx.Data["ContextUser"] = ctx.User ctx.HTML(200, ISSUES) }