From 5087582d1e3f60ac0119927d86d64c2ad71c8f77 Mon Sep 17 00:00:00 2001 From: Fabio Teixeira Date: Tue, 19 May 2015 10:59:23 -0300 Subject: [PATCH] Add option to clone an article --- app/controllers/my_profile/cms_controller.rb | 8 +++++++- app/helpers/application_helper.rb | 13 +++++++++++++ app/models/article.rb | 15 +++++++-------- app/views/content_viewer/_article_toolbar.html.erb | 4 ++++ plugins/tolerance_time/lib/tolerance_time_plugin.rb | 13 +++++++++++-- test/functional/cms_controller_test.rb | 8 ++++++++ test/functional/content_viewer_controller_test.rb | 2 ++ test/unit/application_helper_test.rb | 8 ++++++++ 8 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/controllers/my_profile/cms_controller.rb b/app/controllers/my_profile/cms_controller.rb index 655e3c4..3559cd5 100644 --- a/app/controllers/my_profile/cms_controller.rb +++ b/app/controllers/my_profile/cms_controller.rb @@ -144,7 +144,13 @@ class CmsController < MyProfileController article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {} article_data.merge!(params[:article]) if params[:article] article_data.merge!(:profile => profile) if profile - @article = klass.new(article_data) + + @article = if params[:clone] + current_article = profile.articles.find(params[:id]) + current_article.copy_without_save + else + klass.new(article_data) + end parent = check_parent(params[:parent_id]) if parent diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 64ee933..20b9a12 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -931,6 +931,19 @@ module ApplicationHelper article_helper.cms_label_for_edit end + def label_for_clone_article(article) + translated_types = { + Folder => _('Folder'), + Blog => _('Blog'), + Event => _('Event'), + Forum => _('Forum') + } + + translated_type = translated_types[article.class] || _('Article') + + _('Clone %s') % translated_type + end + def add_rss_feed_to_head(title, url) content_for :feeds do tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url)) diff --git a/app/models/article.rb b/app/models/article.rb index bc6e5f5..04516a7 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -577,25 +577,24 @@ class Article < ActiveRecord::Base profile.visible? && profile.public? && published? end - - def copy(options = {}) + def copy_without_save(options = {}) attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } attrs.merge!(options) object = self.class.new attrs.each do |key, value| object.send(key.to_s+'=', value) end + object + end + + def copy(options = {}) + object = copy_without_save(options) object.save object end def copy!(options = {}) - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } - attrs.merge!(options) - object = self.class.new - attrs.each do |key, value| - object.send(key.to_s+'=', value) - end + object = copy_without_save(options) object.save! object end diff --git a/app/views/content_viewer/_article_toolbar.html.erb b/app/views/content_viewer/_article_toolbar.html.erb index bf4f50f..e7aaeac 100644 --- a/app/views/content_viewer/_article_toolbar.html.erb +++ b/app/views/content_viewer/_article_toolbar.html.erb @@ -30,6 +30,10 @@ <% end %> <%= 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) %> + + <% content = content_tag('span', label_for_clone_article(@page)) %> + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %> + <%= expirable_button @page, :clone, content, url %> <% end %> <% if @page.accept_uploads? && @page.allow_create?(user) %> diff --git a/plugins/tolerance_time/lib/tolerance_time_plugin.rb b/plugins/tolerance_time/lib/tolerance_time_plugin.rb index 4fbeb7f..920a52e 100644 --- a/plugins/tolerance_time/lib/tolerance_time_plugin.rb +++ b/plugins/tolerance_time/lib/tolerance_time_plugin.rb @@ -56,9 +56,18 @@ class ToleranceTimePlugin < Noosfero::Plugin end def content_expire_edit(content) + content_expire_for(content, _('editing')) + end + + def content_expire_clone(content) + content_expire_for(content, _('cloning')) + end + + private + + def content_expire_for(content, action) if ToleranceTimePlugin.expired?(content) - _('The tolerance time for editing this content is over.') + _('The tolerance time for %s this content is over.') % action end end - end diff --git a/test/functional/cms_controller_test.rb b/test/functional/cms_controller_test.rb index 69a0ef4..11d1ed7 100644 --- a/test/functional/cms_controller_test.rb +++ b/test/functional/cms_controller_test.rb @@ -1811,6 +1811,14 @@ class CmsControllerTest < ActionController::TestCase assert_equal 'first version', assigns(:article).name end + should 'clone article with its content' do + article = profile.articles.create(:name => 'first version') + + get :new, :profile => profile.identifier, :id => article.id, :clone => true, :type => 'TinyMceArticle' + + assert_match article.name, @response.body + end + should 'save article with content from older version' do article = profile.articles.create(:name => 'first version') article.name = 'second version'; article.save diff --git a/test/functional/content_viewer_controller_test.rb b/test/functional/content_viewer_controller_test.rb index b2bc944..6a449e0 100644 --- a/test/functional/content_viewer_controller_test.rb +++ b/test/functional/content_viewer_controller_test.rb @@ -1252,9 +1252,11 @@ class ContentViewerControllerTest < ActionController::TestCase should 'expire article actions button if any plugins says so' do class Plugin1 < Noosfero::Plugin def content_expire_edit(content); 'This button is expired.'; end + def content_expire_clone(content); 'This button is expired.'; end end class Plugin2 < Noosfero::Plugin def content_expire_edit(content); nil; end + def content_expire_clone(content); nil; end end Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) diff --git a/test/unit/application_helper_test.rb b/test/unit/application_helper_test.rb index a3661e6..4c7ae44 100644 --- a/test/unit/application_helper_test.rb +++ b/test/unit/application_helper_test.rb @@ -1009,6 +1009,14 @@ class ApplicationHelperTest < ActionView::TestCase assert html.include?("onClick=\"toggle_fullwidth('#article')\"") end + should "return the related class string" do + assert_equal "Clone Folder", label_for_clone_article(Folder.new) + assert_equal "Clone Blog", label_for_clone_article(Blog.new) + assert_equal "Clone Event", label_for_clone_article(Event.new) + assert_equal "Clone Forum", label_for_clone_article(Forum.new) + assert_equal "Clone Article", label_for_clone_article(TinyMceArticle.new) + end + protected include NoosferoTestHelper -- libgit2 0.21.2