1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
# frozen_string_literal: true
module Notes
class UpdateService < BaseService
def execute(note)
Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification.temporary_ignore_tables_in_transaction(
%w[
notes
vulnerability_user_mentions
], url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/482742'
) do
return note unless note.editable? && params.present? # rubocop:disable Cop/AvoidReturnFromBlocks -- Temp for decomp exemption
old_mentioned_users = note.mentioned_users(current_user).to_a
note.assign_attributes(params)
return note unless note.valid? # rubocop:disable Cop/AvoidReturnFromBlocks -- Temp for decomp exemption
track_note_edit_usage_for_issues(note) if note.for_issue?
track_note_edit_usage_for_merge_requests(note) if note.for_merge_request?
only_commands = false
quick_actions_service = QuickActionsService.new(project, current_user)
if quick_actions_service.supported?(note)
content, update_params, message, command_names = quick_actions_service.execute(note, {})
only_commands = content.empty?
note.note = content
status = ::Notes::QuickActionsStatus.new(
command_names: command_names, commands_only: only_commands)
status.add_message(message)
note.quick_actions_status = status
end
update_note(note, only_commands)
note.save
unless only_commands || note.for_personal_snippet?
note.create_new_cross_references!(current_user)
update_todos(note, old_mentioned_users)
update_suggestions(note)
execute_note_webhook(note)
end
if quick_actions_service.commands_executed_count.to_i > 0
if update_params.present?
quick_actions_service.apply_updates(update_params, note)
note.commands_changes = update_params
end
if only_commands
delete_note(note, message)
else
note.save
end
end
note
end
end
private
def update_note(note, only_commands)
return unless note.note_changed?
note.assign_attributes(last_edited_at: Time.current, updated_by: current_user)
note.check_for_spam(action: :update, user: current_user) unless only_commands
end
def delete_note(note, message)
note.quick_actions_status.add_error(_('Commands did not apply')) if message.blank?
Notes::DestroyService.new(project, current_user).execute(note)
end
def update_suggestions(note)
return unless note.supports_suggestion?
Suggestion.transaction do
note.suggestions.delete_all
Suggestions::CreateService.new(note).execute
end
# We need to refresh the previous suggestions call cache
# in order to get the new records.
note.reset
end
def update_todos(note, old_mentioned_users)
return unless note.previous_changes.include?('note')
TodoService.new.update_note(note, current_user, old_mentioned_users)
end
def track_note_edit_usage_for_issues(note)
Gitlab::UsageDataCounters::IssueActivityUniqueCounter.track_issue_comment_edited_action(
author: note.author,
project: project
)
end
def execute_note_webhook(note)
return unless note.project && note.previous_changes.include?('note')
note_data = Gitlab::DataBuilder::Note.build(note, note.author, :update)
is_confidential = note.confidential?(include_noteable: true)
hooks_scope = is_confidential ? :confidential_note_hooks : :note_hooks
note.project.execute_hooks(note_data, hooks_scope)
end
def track_note_edit_usage_for_merge_requests(note)
Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter.track_edit_comment_action(note: note)
end
end
end
Notes::UpdateService.prepend_mod_with('Notes::UpdateService')
|