mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 08:15:48 +08:00
0924f874bd
We've had the UploadReference table for some time now in core, but it was added after ChatUpload was and chat was just never moved over to this new system. This commit changes all chat code dealing with uploads to create/ update/delete/query UploadReference records instead of ChatUpload records for consistency. At a later date we will drop the ChatUpload table, but for now keeping it for data backup. The migration + post migration are the same, we need both in case any chat uploads are added/removed during deploy.
99 lines
2.9 KiB
Ruby
99 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Chat::ChatMessageUpdater
|
|
attr_reader :error
|
|
|
|
def self.update(opts)
|
|
instance = new(**opts)
|
|
instance.update
|
|
instance
|
|
end
|
|
|
|
def initialize(guardian:, chat_message:, new_content:, upload_ids: nil)
|
|
@guardian = guardian
|
|
@user = guardian.user
|
|
@chat_message = chat_message
|
|
@old_message_content = chat_message.message
|
|
@chat_channel = @chat_message.chat_channel
|
|
@new_content = new_content
|
|
@upload_ids = upload_ids
|
|
@error = nil
|
|
end
|
|
|
|
def update
|
|
begin
|
|
validate_channel_status!
|
|
@guardian.ensure_can_edit_chat!(@chat_message)
|
|
@chat_message.message = @new_content
|
|
@chat_message.last_editor_id = @user.id
|
|
upload_info = get_upload_info
|
|
validate_message!(has_uploads: upload_info[:uploads].any?)
|
|
@chat_message.cook
|
|
@chat_message.save!
|
|
update_uploads(upload_info)
|
|
revision = save_revision!
|
|
@chat_message.reload
|
|
ChatPublisher.publish_edit!(@chat_channel, @chat_message)
|
|
Jobs.enqueue(:process_chat_message, { chat_message_id: @chat_message.id })
|
|
Chat::ChatNotifier.notify_edit(chat_message: @chat_message, timestamp: revision.created_at)
|
|
DiscourseEvent.trigger(:chat_message_edited, @chat_message, @chat_channel, @user)
|
|
rescue => error
|
|
@error = error
|
|
end
|
|
end
|
|
|
|
def failed?
|
|
@error.present?
|
|
end
|
|
|
|
private
|
|
|
|
def validate_channel_status!
|
|
return if @guardian.can_modify_channel_message?(@chat_channel)
|
|
raise StandardError.new(
|
|
I18n.t(
|
|
"chat.errors.channel_modify_message_disallowed",
|
|
status: @chat_channel.status_name,
|
|
),
|
|
)
|
|
end
|
|
|
|
def validate_message!(has_uploads:)
|
|
@chat_message.validate_message(has_uploads: has_uploads)
|
|
if @chat_message.errors.present?
|
|
raise StandardError.new(@chat_message.errors.map(&:full_message).join(", "))
|
|
end
|
|
end
|
|
|
|
def get_upload_info
|
|
return { uploads: [] } if @upload_ids.nil? || !SiteSetting.chat_allow_uploads
|
|
|
|
uploads = Upload.where(id: @upload_ids, user_id: @user.id)
|
|
if uploads.count != @upload_ids.count
|
|
# User is passing upload_ids for uploads that they don't own. Don't change anything.
|
|
return { uploads: @chat_message.uploads, changed: false }
|
|
end
|
|
|
|
new_upload_ids = uploads.map(&:id)
|
|
existing_upload_ids = @chat_message.upload_ids
|
|
difference = (existing_upload_ids + new_upload_ids) - (existing_upload_ids & new_upload_ids)
|
|
{ uploads: uploads, changed: difference.any? }
|
|
end
|
|
|
|
def update_uploads(upload_info)
|
|
return unless upload_info[:changed]
|
|
|
|
DB.exec("DELETE FROM chat_uploads WHERE chat_message_id = #{@chat_message.id}")
|
|
UploadReference.where(target: @chat_message).destroy_all
|
|
@chat_message.attach_uploads(upload_info[:uploads])
|
|
end
|
|
|
|
def save_revision!
|
|
@chat_message.revisions.create!(
|
|
old_message: @old_message_content,
|
|
new_message: @chat_message.message,
|
|
user_id: @user.id,
|
|
)
|
|
end
|
|
end
|