Commit 5087582d1e3f60ac0119927d86d64c2ad71c8f77
Committed by
Rodrigo Souto
1 parent
9984b8c2
Exists in
master
and in
29 other branches
Add option to clone an article
Signed-off-by: Arthur Del Esposte <arthurmde@gmail.com> Signed-off-by: Fabio Teixeira <fabio1079@gmail.com>
Showing
8 changed files
with
60 additions
and
11 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
| ... | ... | @@ -144,7 +144,13 @@ class CmsController < MyProfileController |
| 144 | 144 | article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {} |
| 145 | 145 | article_data.merge!(params[:article]) if params[:article] |
| 146 | 146 | article_data.merge!(:profile => profile) if profile |
| 147 | - @article = klass.new(article_data) | |
| 147 | + | |
| 148 | + @article = if params[:clone] | |
| 149 | + current_article = profile.articles.find(params[:id]) | |
| 150 | + current_article.copy_without_save | |
| 151 | + else | |
| 152 | + klass.new(article_data) | |
| 153 | + end | |
| 148 | 154 | |
| 149 | 155 | parent = check_parent(params[:parent_id]) |
| 150 | 156 | if parent | ... | ... |
app/helpers/application_helper.rb
| ... | ... | @@ -931,6 +931,19 @@ module ApplicationHelper |
| 931 | 931 | article_helper.cms_label_for_edit |
| 932 | 932 | end |
| 933 | 933 | |
| 934 | + def label_for_clone_article(article) | |
| 935 | + translated_types = { | |
| 936 | + Folder => _('Folder'), | |
| 937 | + Blog => _('Blog'), | |
| 938 | + Event => _('Event'), | |
| 939 | + Forum => _('Forum') | |
| 940 | + } | |
| 941 | + | |
| 942 | + translated_type = translated_types[article.class] || _('Article') | |
| 943 | + | |
| 944 | + _('Clone %s') % translated_type | |
| 945 | + end | |
| 946 | + | |
| 934 | 947 | def add_rss_feed_to_head(title, url) |
| 935 | 948 | content_for :feeds do |
| 936 | 949 | tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url)) | ... | ... |
app/models/article.rb
| ... | ... | @@ -577,25 +577,24 @@ class Article < ActiveRecord::Base |
| 577 | 577 | profile.visible? && profile.public? && published? |
| 578 | 578 | end |
| 579 | 579 | |
| 580 | - | |
| 581 | - def copy(options = {}) | |
| 580 | + def copy_without_save(options = {}) | |
| 582 | 581 | attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } |
| 583 | 582 | attrs.merge!(options) |
| 584 | 583 | object = self.class.new |
| 585 | 584 | attrs.each do |key, value| |
| 586 | 585 | object.send(key.to_s+'=', value) |
| 587 | 586 | end |
| 587 | + object | |
| 588 | + end | |
| 589 | + | |
| 590 | + def copy(options = {}) | |
| 591 | + object = copy_without_save(options) | |
| 588 | 592 | object.save |
| 589 | 593 | object |
| 590 | 594 | end |
| 591 | 595 | |
| 592 | 596 | def copy!(options = {}) |
| 593 | - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } | |
| 594 | - attrs.merge!(options) | |
| 595 | - object = self.class.new | |
| 596 | - attrs.each do |key, value| | |
| 597 | - object.send(key.to_s+'=', value) | |
| 598 | - end | |
| 597 | + object = copy_without_save(options) | |
| 599 | 598 | object.save! |
| 600 | 599 | object |
| 601 | 600 | end | ... | ... |
app/views/content_viewer/_article_toolbar.html.erb
| ... | ... | @@ -30,6 +30,10 @@ |
| 30 | 30 | <% end %> |
| 31 | 31 | |
| 32 | 32 | <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> |
| 33 | + | |
| 34 | + <% content = content_tag('span', label_for_clone_article(@page)) %> | |
| 35 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %> | |
| 36 | + <%= expirable_button @page, :clone, content, url %> | |
| 33 | 37 | <% end %> |
| 34 | 38 | |
| 35 | 39 | <% if @page.accept_uploads? && @page.allow_create?(user) %> | ... | ... |
plugins/tolerance_time/lib/tolerance_time_plugin.rb
| ... | ... | @@ -56,9 +56,18 @@ class ToleranceTimePlugin < Noosfero::Plugin |
| 56 | 56 | end |
| 57 | 57 | |
| 58 | 58 | def content_expire_edit(content) |
| 59 | + content_expire_for(content, _('editing')) | |
| 60 | + end | |
| 61 | + | |
| 62 | + def content_expire_clone(content) | |
| 63 | + content_expire_for(content, _('cloning')) | |
| 64 | + end | |
| 65 | + | |
| 66 | + private | |
| 67 | + | |
| 68 | + def content_expire_for(content, action) | |
| 59 | 69 | if ToleranceTimePlugin.expired?(content) |
| 60 | - _('The tolerance time for editing this content is over.') | |
| 70 | + _('The tolerance time for %s this content is over.') % action | |
| 61 | 71 | end |
| 62 | 72 | end |
| 63 | - | |
| 64 | 73 | end | ... | ... |
test/functional/cms_controller_test.rb
| ... | ... | @@ -1811,6 +1811,14 @@ class CmsControllerTest < ActionController::TestCase |
| 1811 | 1811 | assert_equal 'first version', assigns(:article).name |
| 1812 | 1812 | end |
| 1813 | 1813 | |
| 1814 | + should 'clone article with its content' do | |
| 1815 | + article = profile.articles.create(:name => 'first version') | |
| 1816 | + | |
| 1817 | + get :new, :profile => profile.identifier, :id => article.id, :clone => true, :type => 'TinyMceArticle' | |
| 1818 | + | |
| 1819 | + assert_match article.name, @response.body | |
| 1820 | + end | |
| 1821 | + | |
| 1814 | 1822 | should 'save article with content from older version' do |
| 1815 | 1823 | article = profile.articles.create(:name => 'first version') |
| 1816 | 1824 | article.name = 'second version'; article.save | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -1252,9 +1252,11 @@ class ContentViewerControllerTest < ActionController::TestCase |
| 1252 | 1252 | should 'expire article actions button if any plugins says so' do |
| 1253 | 1253 | class Plugin1 < Noosfero::Plugin |
| 1254 | 1254 | def content_expire_edit(content); 'This button is expired.'; end |
| 1255 | + def content_expire_clone(content); 'This button is expired.'; end | |
| 1255 | 1256 | end |
| 1256 | 1257 | class Plugin2 < Noosfero::Plugin |
| 1257 | 1258 | def content_expire_edit(content); nil; end |
| 1259 | + def content_expire_clone(content); nil; end | |
| 1258 | 1260 | end |
| 1259 | 1261 | Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) |
| 1260 | 1262 | ... | ... |
test/unit/application_helper_test.rb
| ... | ... | @@ -1009,6 +1009,14 @@ class ApplicationHelperTest < ActionView::TestCase |
| 1009 | 1009 | assert html.include?("onClick=\"toggle_fullwidth('#article')\"") |
| 1010 | 1010 | end |
| 1011 | 1011 | |
| 1012 | + should "return the related class string" do | |
| 1013 | + assert_equal "Clone Folder", label_for_clone_article(Folder.new) | |
| 1014 | + assert_equal "Clone Blog", label_for_clone_article(Blog.new) | |
| 1015 | + assert_equal "Clone Event", label_for_clone_article(Event.new) | |
| 1016 | + assert_equal "Clone Forum", label_for_clone_article(Forum.new) | |
| 1017 | + assert_equal "Clone Article", label_for_clone_article(TinyMceArticle.new) | |
| 1018 | + end | |
| 1019 | + | |
| 1012 | 1020 | protected |
| 1013 | 1021 | include NoosferoTestHelper |
| 1014 | 1022 | ... | ... |