app/controllers/plan_my_stuff/comments_controller.rb



# frozen_string_literal: true

module PlanMyStuff
  class CommentsController < PlanMyStuff::ApplicationController
    # POST /issues/:issue_id/comments
    def create
      @issue = PlanMyStuff::Issue.find(params[:issue_id].to_i, repo: params[:repo])

      PlanMyStuff::Comment.create!(
        issue: @issue,
        body: comment_params[:body],
        user: pms_current_user,
        visibility: comment_params[:visibility]&.to_sym || :public,
        waiting_on_reply: comment_params[:waiting_on_reply] == '1',
      )

      flash[:success] = 'Comment was successfully created.'
      redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
    rescue PlanMyStuff::LockedIssueError => e
      pms_handle_rescue(e)
      flash[:error] = 'This issue is locked; no new comments can be posted.'
      redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
    end

    # GET /issues/:issue_id/comments/:id/edit
    def edit
      load_comment
      return unless @comment
      return redirect_to_issue if issue_body_comment?
      return if can_edit?(@comment)

      redirect_to_unauthorized(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
    end

    # PATCH/PUT /issues/:issue_id/comments/:id
    def update
      load_comment
      return unless @comment
      return redirect_to_issue if issue_body_comment?

      unless can_edit?(@comment)
        redirect_to_unauthorized(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))

        return
      end

      update_attrs = { body: comment_params[:body] }
      update_attrs[:visibility] = comment_params[:visibility].to_sym if @support_user && comment_params[:visibility]

      @comment.update!(**update_attrs, user: pms_current_user)

      flash[:success] = 'Comment was successfully updated.'
      redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
    rescue PlanMyStuff::StaleObjectError => e
      pms_handle_rescue(e)
      flash.now[:error] = 'Comment was modified by someone else. Please review the latest changes and try again.'
      render(:edit, status: PlanMyStuff.unprocessable_status)
    end

    private

      # @return [ActionController::Parameters]
      def comment_params
        params.require(:comment).permit(:body, :visibility, :waiting_on_reply)
      end

      # Loads the issue and comment from params.
      #
      # @return [void]
      #
      def load_comment
        @issue = PlanMyStuff::Issue.find(params[:issue_id].to_i, repo: params[:repo])
        @comment = PlanMyStuff::Comment.find(params[:id].to_i, issue: @issue)
      end

      # Returns true if the current user can edit the given comment. Support users can edit any comment. Regular users
      # can only edit their own comments.
      #
      # @param comment [PlanMyStuff::Comment]
      #
      # @return [Boolean]
      #
      def can_edit?(comment)
        return true if support_user?

        user = pms_current_user
        return false if user.blank?

        comment.metadata.created_by == PlanMyStuff::UserResolver.user_id(user)
      end

      # @return [Boolean]
      def issue_body_comment?
        @comment.metadata.issue_body?
      end

      # @return [void]
      def redirect_to_issue
        redirect_to(plan_my_stuff.issue_path(@issue.number, repo: @issue.repo.full_name))
      end
  end
end