diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 48fbafe440..e856f0e413 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -40,7 +40,8 @@ class WikiPage < ActiveRecord::Base :permission => :view_wiki_pages, :project_key => "#{Wiki.table_name}.project_id" - attr_accessor :redirect_existing_links + + attr_accessor :redirect_existing_links, :deleted_attachment_ids validates_presence_of :title validates_format_of :title, :with => /\A[^,\.\/\?\;\|\s]*\z/ @@ -51,7 +52,7 @@ class WikiPage < ActiveRecord::Base validate :validate_parent_title before_destroy :delete_redirects before_save :handle_rename_or_move, :update_wiki_start_page - after_save :handle_children_move + after_save :handle_children_move, :delete_selected_attachments # eager load information about last updates, without loading text scope :with_updated_on, lambda { preload(:content_without_text) } @@ -65,7 +66,10 @@ class WikiPage < ActiveRecord::Base safe_attributes 'is_start_page', :if => lambda {|page, user| user.allowed_to?(:manage_wiki, page.project)} - def initialize(attributes=nil, *args) + safe_attributes 'deleted_attachment_ids', + :if => lambda {|page, user| page.attachments_deletable?(user)} + + def initialize(attributes=nil, *args) super if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase) self.protected = true @@ -251,6 +255,17 @@ class WikiPage < ActiveRecord::Base ret end + def deleted_attachment_ids + Array(@deleted_attachment_ids).map(&:to_i) + end + + def delete_selected_attachments + if deleted_attachment_ids.present? + objects = attachments.where(:id => deleted_attachment_ids.map(&:to_i)) + attachments.delete(objects) + end + end + protected def validate_parent_title diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb index a1fc3d0053..6ec1db8e1b 100644 --- a/app/views/wiki/edit.html.erb +++ b/app/views/wiki/edit.html.erb @@ -16,6 +16,7 @@ <%= text_area_tag 'content[text]', @text, :cols => 100, :rows => 25, :class => 'wiki-edit', :accesskey => accesskey(:edit) %> +
<% if @page.safe_attribute_names.include?('parent_id') && @wiki.pages.any? %> <%= fields_for @page do |fp| %>

@@ -30,7 +31,30 @@ <% end %>

<%= f.text_field :comments, :size => 120, :maxlength => 1024 %>

-

<%= render :partial => 'attachments/form' %>

+
+
+<%=l(:label_attachment_plural)%> +<% if @page.attachments.any? && @page.safe_attribute?('deleted_attachment_ids') %> +
<%= link_to l(:label_edit_attachments), '#', :onclick => "$('#existing-attachments').toggle(); return false;" %>
+
+ <% @page.attachments.each do |attachment| %> + + <%= text_field_tag '', attachment.filename, :class => "icon icon-attachment filename", :disabled => true %> + + + <% end %> +
+
+<% end %> +
+ <%= render :partial => 'attachments/form' %> +
+

diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index 6b04d9b7c7..3007bf2351 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -695,6 +695,11 @@ html>body .tabular p {overflow:hidden;} width: 175px; } +.tabular .wiki-items label { + margin-left: -260px; + width: 175px; +} + .tabular label.floating{ font-weight: normal; margin-left: 0px; diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index c0a169d7b5..8555410f64 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -459,6 +459,44 @@ class WikiControllerTest < Redmine::ControllerTest assert_equal 1, page.content.version end + def test_update_with_deleted_attachment_ids + @request.session[:user_id] = 2 + page = WikiPage.find(4) + attachment = page.attachments.first + assert_difference 'Attachment.count', -1 do + put :update, :params => { + :project_id => page.wiki.project.id, + :id => page.title, + :content => { + :comments => 'delete file', # failure here, comment is too long + :text => 'edited' + }, + :wiki_page => {:deleted_attachment_ids => [attachment.id]} + } + end + page.reload + refute_includes page.attachments, attachment + end + + def test_update_with_deleted_attachment_ids_and_failure_should_preserve_selected_attachments + @request.session[:user_id] = 2 + page = WikiPage.find(4) + attachment = page.attachments.first + assert_no_difference 'Attachment.count' do + put :update, :params => { + :project_id => page.wiki.project.id, + :id => page.title, + :content => { + :comments => 'a' * 1300, # failure here, comment is too long + :text => 'edited' + }, + :wiki_page => {:deleted_attachment_ids => [attachment.id]} + } + end + page.reload + assert_includes page.attachments, attachment + end + def test_update_stale_page_should_not_raise_an_error @request.session[:user_id] = 2 c = Wiki.find(1).find_page('Another_page').content