Commit 15390f79e01220faaf11994dcc83122f4e711930
Committed by
Antonio Terceiro
1 parent
483065d8
Exists in
master
and in
29 other branches
ActionItem774: allowing upload of more than one file at once
Showing
10 changed files
with
150 additions
and
15 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -101,12 +101,8 @@ class CmsController < MyProfileController | @@ -101,12 +101,8 @@ class CmsController < MyProfileController | ||
101 | klass = @type.constantize | 101 | klass = @type.constantize |
102 | @article = klass.new(params[:article]) | 102 | @article = klass.new(params[:article]) |
103 | 103 | ||
104 | - | ||
105 | - if params[:parent_id] | ||
106 | - parent = profile.articles.find(params[:parent_id]) | ||
107 | - if ! parent.allow_children? | ||
108 | - raise ArgumentError.new("cannot create child of article which does not accept children") | ||
109 | - end | 104 | + parent = check_parent(params[:parent_id]) |
105 | + if parent | ||
110 | @article.parent = parent | 106 | @article.parent = parent |
111 | @parent_id = parent.id | 107 | @parent_id = parent.id |
112 | end | 108 | end |
@@ -134,6 +130,26 @@ class CmsController < MyProfileController | @@ -134,6 +130,26 @@ class CmsController < MyProfileController | ||
134 | redirect_to :action => 'view', :id => @article.id | 130 | redirect_to :action => 'view', :id => @article.id |
135 | end | 131 | end |
136 | 132 | ||
133 | + def upload_files | ||
134 | + @uploaded_files = [] | ||
135 | + @parent = check_parent(params[:parent_id]) | ||
136 | + if request.post? && params[:uploaded_files] | ||
137 | + params[:uploaded_files].each do |file| | ||
138 | + @uploaded_files << UploadedFile.create(:uploaded_data => file, :profile => profile, :parent => @parent) unless file == '' | ||
139 | + end | ||
140 | + @errors = @uploaded_files.select { |f| f.errors.any? } | ||
141 | + if @errors.any? | ||
142 | + render :action => 'upload_files', :parent_id => @parent_id | ||
143 | + else | ||
144 | + redirect_to( if @parent | ||
145 | + {:action => 'view', :id => @parent.id} | ||
146 | + else | ||
147 | + {:action => 'index'} | ||
148 | + end) | ||
149 | + end | ||
150 | + end | ||
151 | + end | ||
152 | + | ||
137 | def destroy | 153 | def destroy |
138 | @article = profile.articles.find(params[:id]) | 154 | @article = profile.articles.find(params[:id]) |
139 | if request.post? | 155 | if request.post? |
@@ -215,5 +231,17 @@ class CmsController < MyProfileController | @@ -215,5 +231,17 @@ class CmsController < MyProfileController | ||
215 | (available_article_types + special_article_types).map {|item| item.name}.include?(type) | 231 | (available_article_types + special_article_types).map {|item| item.name}.include?(type) |
216 | end | 232 | end |
217 | 233 | ||
234 | + def check_parent(id) | ||
235 | + if id | ||
236 | + parent = profile.articles.find(id) | ||
237 | + if ! parent.allow_children? | ||
238 | + raise ArgumentError.new("cannot create child of article which does not accept children") | ||
239 | + end | ||
240 | + parent | ||
241 | + else | ||
242 | + nil | ||
243 | + end | ||
244 | + end | ||
245 | + | ||
218 | end | 246 | end |
219 | 247 |
app/helpers/cms_helper.rb
@@ -9,6 +9,12 @@ module CmsHelper | @@ -9,6 +9,12 @@ module CmsHelper | ||
9 | mime_type.gsub('/', '_').gsub('-', '') | 9 | mime_type.gsub('/', '_').gsub('-', '') |
10 | end | 10 | end |
11 | 11 | ||
12 | + def add_upload_file_field(name) | ||
13 | + button_to_function :add, name, nil do |page| | ||
14 | + page.insert_html :bottom, :uploaded_files, :partial => 'upload_file', :object => UploadedFile.new | ||
15 | + end | ||
16 | + end | ||
17 | + | ||
12 | attr_reader :environment | 18 | attr_reader :environment |
13 | 19 | ||
14 | def options_for_article(article) | 20 | def options_for_article(article) |
app/models/uploaded_file.rb
@@ -11,7 +11,9 @@ class UploadedFile < Article | @@ -11,7 +11,9 @@ class UploadedFile < Article | ||
11 | # :max_size => 5.megabytes | 11 | # :max_size => 5.megabytes |
12 | has_attachment :storage => :file_system, | 12 | has_attachment :storage => :file_system, |
13 | :thumbnails => { :icon => [24,24] }, | 13 | :thumbnails => { :icon => [24,24] }, |
14 | - :thumbnail_class => Thumbnail | 14 | + :thumbnail_class => Thumbnail, |
15 | + :max_size => 5.megabytes, | ||
16 | + :resize_to => '640x480>' | ||
15 | 17 | ||
16 | def self.max_size | 18 | def self.max_size |
17 | UploadedFile.attachment_options[:max_size] | 19 | UploadedFile.attachment_options[:max_size] |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +<p><%= file_field_tag('uploaded_files[]') %></p> |
app/views/cms/_uploaded_file.rhtml
1 | -<%= required_fields_message %> | ||
2 | - | ||
3 | -<%= required labelled_form_field(_("Select the file you want to upload (max size %s).") % UploadedFile.max_size.to_humanreadable, file_field(:article, :uploaded_data)) %> | ||
4 | - | ||
5 | <%= labelled_form_field(_('Describe this file:'), text_area(:article, :abstract)) %> | 1 | <%= labelled_form_field(_('Describe this file:'), text_area(:article, :abstract)) %> |
@@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
1 | +<% if @errors %> | ||
2 | + <div class="errorExplanation" id="errorExplanation"> | ||
3 | + <h2><%= n_('This file couldn\'t be saved', 'These %{num} files couldn\'t be saved', @errors.size) % { :num => @errors.size } %></h2> | ||
4 | + <p><%= _('There were problems with the following files:') %> </p> | ||
5 | + <ul> | ||
6 | + <% for file in @uploaded_files %> | ||
7 | + <% for msg in file.errors.full_messages %> | ||
8 | + <li><strong><%= file.name %></strong> : <%= msg %></li> | ||
9 | + <% end %> | ||
10 | + <% end %> | ||
11 | + </ul> | ||
12 | + </div> | ||
13 | + | ||
14 | +<% end %> | ||
15 | + | ||
16 | +<h2><%= _('Publish media') %></h2> | ||
17 | + | ||
18 | +<h3><%= _("Select the files you want to upload (max size %s):") % UploadedFile.max_size.to_humanreadable %></h3> | ||
19 | +<h4><%= _('Photos/Videos/Audio/Documents') %></h4> | ||
20 | + | ||
21 | +<% form_for('uploaded_file', :url => { :action => 'upload_files' }, :html => {:multipart => true}) do |f| %> | ||
22 | + | ||
23 | + <div id='uploaded_files'> | ||
24 | + <%= render :partial => 'upload_file' %> | ||
25 | + </div> | ||
26 | + | ||
27 | + <%= hidden_field_tag('parent_id', @parent.id) if @parent %> | ||
28 | + | ||
29 | + <% button_bar do %> | ||
30 | + <%= add_upload_file_field _('More files') %> | ||
31 | + <%= submit_button :save, _('Upload'), :cancel => {:action => (@parent ? 'view' : 'index'), :id => @parent } %> | ||
32 | + <% end %> | ||
33 | + | ||
34 | +<% end %> |
app/views/cms/view.rhtml
@@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
18 | <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %> | 18 | <%= button :add, _('New folder'), :action => 'new', :type => 'Folder', :parent_id => parent_id %> |
19 | <% end %> | 19 | <% end %> |
20 | <%= lightbox_button('new', label_for_new_article(@article), :action => 'new', :parent_id => parent_id) %> | 20 | <%= lightbox_button('new', label_for_new_article(@article), :action => 'new', :parent_id => parent_id) %> |
21 | - <%= button('save', _('Upload file'), :action => 'new', :parent_id => parent_id, :type => 'UploadedFile') %> | 21 | + <%= button('upload-file', _('Upload files'), :action => 'upload_files', :parent_id => parent_id) %> |
22 | <% end %> | 22 | <% end %> |
23 | 23 | ||
24 | <table class='cms-articles'> | 24 | <table class='cms-articles'> |
public/designs/icons/default/style.css
@@ -54,3 +54,4 @@ | @@ -54,3 +54,4 @@ | ||
54 | .icon-menu-comments { background-image: url(blog-HC.gif) } | 54 | .icon-menu-comments { background-image: url(blog-HC.gif) } |
55 | .icon-menu-people { background-image: url(album-HC.gif) } | 55 | .icon-menu-people { background-image: url(album-HC.gif) } |
56 | .icon-menu-mail { background-image: url(mail-HC.gif) } | 56 | .icon-menu-mail { background-image: url(mail-HC.gif) } |
57 | +.icon-upload-file { background-image: url(go-up-HC.gif) } |
test/functional/cms_controller_test.rb
@@ -209,6 +209,62 @@ class CmsControllerTest < Test::Unit::TestCase | @@ -209,6 +209,62 @@ class CmsControllerTest < Test::Unit::TestCase | ||
209 | end | 209 | end |
210 | end | 210 | end |
211 | 211 | ||
212 | + should 'be able to upload more than one file at once' do | ||
213 | + assert_difference UploadedFile, :count, 2 do | ||
214 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain'), fixture_file_upload('/files/rails.png', 'text/plain')] | ||
215 | + end | ||
216 | + assert_not_nil profile.articles.find_by_path('test.txt') | ||
217 | + assert_not_nil profile.articles.find_by_path('rails.png') | ||
218 | + end | ||
219 | + | ||
220 | + should 'upload to rigth folder' do | ||
221 | + f = Folder.new(:name => 'f'); profile.articles << f; f.save! | ||
222 | + post :upload_files, :profile => profile.identifier, :parent_id => f.id, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain')] | ||
223 | + f.reload | ||
224 | + | ||
225 | + assert_not_nil f.children[0] | ||
226 | + assert_equal 'test.txt', f.children[0].name | ||
227 | + end | ||
228 | + | ||
229 | + should 'not crash on empty file' do | ||
230 | + assert_nothing_raised do | ||
231 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain'), '' ] | ||
232 | + end | ||
233 | + assert_not_nil profile.articles.find_by_path('test.txt') | ||
234 | + end | ||
235 | + | ||
236 | + should 'redirect to cms after uploading files' do | ||
237 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain')] | ||
238 | + assert_redirected_to :action => 'index' | ||
239 | + end | ||
240 | + | ||
241 | + should 'redirect to folder after uploading files' do | ||
242 | + f = Folder.new(:name => 'f'); profile.articles << f; f.save! | ||
243 | + post :upload_files, :profile => profile.identifier, :parent_id => f.id, :uploaded_files => [fixture_file_upload('/files/test.txt', 'text/plain')] | ||
244 | + assert_redirected_to :action => 'view', :id => f.id | ||
245 | + end | ||
246 | + | ||
247 | + should 'display error message when file has more than max size' do | ||
248 | + UploadedFile.any_instance.stubs(:size).returns(UploadedFile.attachment_options[:max_size] + 1024) | ||
249 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/rails.png', 'image/png')] | ||
250 | + assert assigns(:uploaded_files).first.size > UploadedFile.attachment_options[:max_size] | ||
251 | + assert_tag :tag => 'div', :attributes => { :class => 'errorExplanation', :id => 'errorExplanation' } | ||
252 | + end | ||
253 | + | ||
254 | + should 'not display error message when file has less than max size' do | ||
255 | + UploadedFile.any_instance.stubs(:size).returns(UploadedFile.attachment_options[:max_size] - 1024) | ||
256 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/rails.png', 'image/png')] | ||
257 | + assert_no_tag :tag => 'div', :attributes => { :class => 'errorExplanation', :id => 'errorExplanation' } | ||
258 | + end | ||
259 | + | ||
260 | + should 'not redirect when some file has errors' do | ||
261 | + UploadedFile.any_instance.stubs(:size).returns(UploadedFile.attachment_options[:max_size] + 1024) | ||
262 | + post :upload_files, :profile => profile.identifier, :uploaded_files => [fixture_file_upload('/files/rails.png', 'image/png')] | ||
263 | + assert_response :success | ||
264 | + assert_template 'upload_files' | ||
265 | + end | ||
266 | + | ||
267 | + | ||
212 | should 'offer to create children' do | 268 | should 'offer to create children' do |
213 | Article.any_instance.stubs(:allow_children?).returns(true) | 269 | Article.any_instance.stubs(:allow_children?).returns(true) |
214 | 270 | ||
@@ -250,8 +306,8 @@ class CmsControllerTest < Test::Unit::TestCase | @@ -250,8 +306,8 @@ class CmsControllerTest < Test::Unit::TestCase | ||
250 | end | 306 | end |
251 | 307 | ||
252 | should 'display max size of uploaded file' do | 308 | should 'display max size of uploaded file' do |
253 | - get :new, :type => UploadedFile.name, :profile => profile.identifier | ||
254 | - assert_tag :tag => 'label', :attributes => { :for => 'article_uploaded_data' }, :content => /max size #{UploadedFile.max_size.to_humanreadable}/ | 309 | + get :upload_files, :profile => profile.identifier |
310 | + assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/ | ||
255 | end | 311 | end |
256 | 312 | ||
257 | should 'display link for selecting categories' do | 313 | should 'display link for selecting categories' do |
@@ -766,5 +822,4 @@ class CmsControllerTest < Test::Unit::TestCase | @@ -766,5 +822,4 @@ class CmsControllerTest < Test::Unit::TestCase | ||
766 | get :edit, :profile => profile.identifier, :id => profile.blog.id | 822 | get :edit, :profile => profile.identifier, :id => profile.blog.id |
767 | assert_tag :tag => 'a', :content => 'Cancel', :attributes => { :href => /\/myprofile\/#{profile.identifier}/ } | 823 | assert_tag :tag => 'a', :content => 'Cancel', :attributes => { :href => /\/myprofile\/#{profile.identifier}/ } |
768 | end | 824 | end |
769 | - | ||
770 | end | 825 | end |
test/unit/uploaded_file_test.rb
@@ -73,4 +73,16 @@ class UploadedFileTest < Test::Unit::TestCase | @@ -73,4 +73,16 @@ class UploadedFileTest < Test::Unit::TestCase | ||
73 | assert_equal false, file.can_display_hits? | 73 | assert_equal false, file.can_display_hits? |
74 | end | 74 | end |
75 | 75 | ||
76 | + should 'not upload files bigger than max_size' do | ||
77 | + f = UploadedFile.new(:profile => @profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | ||
78 | + f.expects(:size).returns(UploadedFile.attachment_options[:max_size] + 1024) | ||
79 | + assert !f.valid? | ||
80 | + end | ||
81 | + | ||
82 | + should 'upload files smaller than max_size' do | ||
83 | + f = UploadedFile.new(:profile => @profile, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')) | ||
84 | + f.expects(:size).returns(UploadedFile.attachment_options[:max_size] - 1024) | ||
85 | + assert f.valid? | ||
86 | + end | ||
87 | + | ||
76 | end | 88 | end |