diff --git a/app/models/message.rb b/app/models/message.rb index c6fe1dc85..205785414 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -51,6 +51,8 @@ class Message < ActiveRecord::Base :author_key => :author_id acts_as_watchable + attr_writer :deleted_attachment_ids + validates_presence_of :board, :subject, :content validates_length_of :subject, :maximum => 255 validate :cannot_reply_to_locked_topic, :on => :create @@ -58,6 +60,7 @@ class Message < ActiveRecord::Base after_create :add_author_as_watcher, :reset_counters! after_update :update_messages_board after_destroy :reset_counters! + after_save :delete_selected_attachments after_create_commit :send_notification scope :visible, (lambda do |*args| @@ -73,6 +76,14 @@ class Message < ActiveRecord::Base user.allowed_to?(:edit_messages, message.project) end ) + safe_attributes( + 'deleted_attachment_ids', + :if => + lambda do |message, user| + message.attachments_deletable?(user) + end + ) + def visible?(user=User.current) !user.nil? && user.allowed_to?(:view_messages, project) end @@ -121,12 +132,23 @@ class Message < ActiveRecord::Base project.notified_users.reject {|user| !visible?(user)} end + def deleted_attachment_ids + Array(@deleted_attachment_ids).map(&:to_i) + end + private def add_author_as_watcher Watcher.create(:watchable => self.root, :user => author) end + def delete_selected_attachments + if deleted_attachment_ids.present? + objects = attachments.where(:id => deleted_attachment_ids) + attachments.delete(objects) + end + end + def send_notification if Setting.notified_events.include?('message_posted') Mailer.deliver_message_posted(self) diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb index e030627a2..db772d564 100644 --- a/app/views/messages/_form.html.erb +++ b/app/views/messages/_form.html.erb @@ -32,6 +32,27 @@ <%= wikitoolbar_for 'message_content', preview_board_message_path(:board_id => @board, :id => @message) %> -

<%= l(:label_attachment_plural) %>
-<%= render :partial => 'attachments/form', :locals => {:container => @message} %>

+
+ <%= l(:label_attachment_plural) %> +<% if @message.attachments.any? && @message.safe_attribute?('deleted_attachment_ids') -%> +
<%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;" %>
+
+ <% @message.attachments.each do |attachment| -%> + + <%= text_field_tag nil, attachment.filename, :id => nil, :class => 'icon icon-attachment filename', :disabled => true %> + + + <% end -%> +
+
+<% end -%> +
+ <%= render :partial => 'attachments/form', :locals => {:container => @message} %> +
+
diff --git a/test/functional/messages_controller_test.rb b/test/functional/messages_controller_test.rb index b42c891a5..0105cb4fb 100644 --- a/test/functional/messages_controller_test.rb +++ b/test/functional/messages_controller_test.rb @@ -21,7 +21,7 @@ require File.expand_path('../../test_helper', __FILE__) class MessagesControllerTest < Redmine::ControllerTest fixtures :projects, :users, :email_addresses, :user_preferences, :members, :member_roles, :roles, :boards, :messages, :enabled_modules, - :watchers + :watchers, :attachments def setup User.current = nil @@ -235,6 +235,29 @@ class MessagesControllerTest < Redmine::ControllerTest assert_equal Board.find(2), message.board end + def test_post_edit_with_deleted_attachment_ids + set_tmp_attachments_directory + @request.session[:user_id] = 2 + message = Message.find(1) + attachment = message.attachments.first + assert_difference 'Attachment.count', -1 do + post( + :edit, + :params => { + :board_id => 1, + :id => 1, + :message => { + :subject => 'New subject', + :content => 'New body', + :deleted_attachment_ids => [attachment.id] + } + } + ) + end + message.reload + assert_not_includes message.attachments, attachment + end + def test_reply @request.session[:user_id] = 2 post(