Commit cd9f3f94df0c36bc9cb01eef2d87dd9e4f288977
Exists in
staging
and in
7 other branches
Merge branch 'AI3133-email_article_to_community_members' into rails3_stable
Conflicts: app/views/content_viewer/_article_toolbar.rhtml
Showing
8 changed files
with
229 additions
and
0 deletions
Show diff stats
app/views/content_viewer/_article_toolbar.html.erb
@@ -37,6 +37,10 @@ | @@ -37,6 +37,10 @@ | ||
37 | <%= colorbox_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) %> | 37 | <%= colorbox_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) %> |
38 | <% end %> | 38 | <% end %> |
39 | 39 | ||
40 | + <% @plugins.dispatch(:article_toolbar_extra_buttons).each do |plugin_button| %> | ||
41 | + <%= instance_eval(&plugin_button) %> | ||
42 | + <% end %> | ||
43 | + | ||
40 | <% if @page.accept_uploads? && @page.allow_create?(user) %> | 44 | <% if @page.accept_uploads? && @page.allow_create?(user) %> |
41 | <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:upload)%> | 45 | <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:upload)%> |
42 | <% end %> | 46 | <% end %> |
@@ -0,0 +1,72 @@ | @@ -0,0 +1,72 @@ | ||
1 | +<div<%= user && " class='logged-in'" %>> | ||
2 | + <div id="article-actions"> | ||
3 | + | ||
4 | + | ||
5 | + <% if @page.allow_edit?(user) && !remove_content_button(:edit) %> | ||
6 | + <% content = content_tag('span', label_for_edit_article(@page)) %> | ||
7 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }) %> | ||
8 | + <%= expirable_button @page, :edit, content, url %> | ||
9 | + <% end %> | ||
10 | + | ||
11 | + <% if @page != profile.home_page && !@page.has_posts? && @page.allow_delete?(user) && !remove_content_button(:delete)%> | ||
12 | + <% content = content_tag( 'span', _('Delete') ) %> | ||
13 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'destroy', :id => @page}) %> | ||
14 | + <% options = {:method => :post, :confirm => delete_article_message(@page)} %> | ||
15 | + <%= expirable_button @page, :delete, content, url, options %> | ||
16 | + <% end %> | ||
17 | + | ||
18 | + <% if !@page.folder? && @page.allow_spread?(user) && !remove_content_button(:spread) %> | ||
19 | + <% content = content_tag( 'span', _('Spread this') ) %> | ||
20 | + <% url = nil %> | ||
21 | + <% if profile.kind_of?(Person) %> | ||
22 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page }) %> | ||
23 | + <% elsif profile.kind_of?(Community) && environment.portal_community %> | ||
24 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'publish_on_portal_community', :id => @page }) %> | ||
25 | + <% end %> | ||
26 | + <%= expirable_button @page, :spread, content, url if url %> | ||
27 | + <% end %> | ||
28 | + | ||
29 | + <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %> | ||
30 | + <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> | ||
31 | + <% content = _('Add translation') %> | ||
32 | + <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> | ||
33 | + <% url = profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => parent_id, :type => @page.type, :article => { :translation_of_id => @page.native_translation.id })%> | ||
34 | + <%= expirable_button @page, :locale, content, url %> | ||
35 | + <% end %> | ||
36 | + | ||
37 | + <%= colorbox_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) %> | ||
38 | + <% end %> | ||
39 | + | ||
40 | + <% | ||
41 | + @plugins.dispatch(:article_toolbar_extra_buttons).each do |plugin_button| %> | ||
42 | + <%= instance_eval(&plugin_button) %> | ||
43 | + <% end %> | ||
44 | + | ||
45 | + <% if @page.accept_uploads? && @page.allow_create?(user) %> | ||
46 | + <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:upload)%> | ||
47 | + <% end %> | ||
48 | + | ||
49 | + <% if !@page.allow_create?(user) && profile.community? && (@page.blog? || @page.parent && @page.parent.blog?) && !remove_content_button(:suggest) %> | ||
50 | + <% content = content_tag( 'span', _('Suggest an article') ) %> | ||
51 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'suggest_an_article'}) %> | ||
52 | + <% options = {:id => 'suggest-article-link'} %> | ||
53 | + <%= expirable_button @page, :suggest, content, url, options %> | ||
54 | + <% end %> | ||
55 | + | ||
56 | + <% if @page.display_versions? %> | ||
57 | + <%= button(:clock, _('All versions'), {:controller => 'content_viewer', :profile => profile.identifier, :action => 'article_versions'}, :id => 'article-versions-link') %> | ||
58 | + <% end %> | ||
59 | + | ||
60 | + <%= report_abuse(profile, :link, @page) %> | ||
61 | + | ||
62 | + </div> | ||
63 | + <div id="article-header"> | ||
64 | + <% if @page.blog? and !@page.image.nil? %> | ||
65 | + <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div> | ||
66 | + <% end %> | ||
67 | + <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> | ||
68 | + <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %> | ||
69 | + <%= article_title(@page, :no_link => true) %> | ||
70 | + <%= article_translations(@page) %> | ||
71 | + </div> | ||
72 | +</div> |
lib/noosfero/plugin.rb
@@ -324,6 +324,17 @@ class Noosfero::Plugin | @@ -324,6 +324,17 @@ class Noosfero::Plugin | ||
324 | nil | 324 | nil |
325 | end | 325 | end |
326 | 326 | ||
327 | + | ||
328 | + # -> Adds buttons to manage members page | ||
329 | + # returns = { :title => title, :icon => icon, :url => url } | ||
330 | + # title = name that will be displayed. | ||
331 | + # icon = css class name (for customized icons include them in a css file). | ||
332 | + # url = url or route to which the button will redirect. | ||
333 | + def article_toolbar_extra_buttons | ||
334 | + nil | ||
335 | + end | ||
336 | + | ||
337 | + | ||
327 | # This method will be called just before a comment is saved to the database. | 338 | # This method will be called just before a comment is saved to the database. |
328 | # | 339 | # |
329 | # It can modify the comment in several ways. In special, a plugin can call | 340 | # It can modify the comment in several ways. In special, a plugin can call |
@@ -611,6 +622,7 @@ class Noosfero::Plugin | @@ -611,6 +622,7 @@ class Noosfero::Plugin | ||
611 | %w[edit delete spread locale suggest home new upload undo] | 622 | %w[edit delete spread locale suggest home new upload undo] |
612 | end | 623 | end |
613 | 624 | ||
625 | + | ||
614 | end | 626 | end |
615 | 627 | ||
616 | require 'noosfero/plugin/hot_spot' | 628 | require 'noosfero/plugin/hot_spot' |
plugins/email_article/controllers/email_article_plugin_myprofile_controller.rb
0 → 100644
@@ -0,0 +1,47 @@ | @@ -0,0 +1,47 @@ | ||
1 | +class EmailArticlePluginMyprofileController < MyProfileController | ||
2 | + | ||
3 | + needs_profile | ||
4 | + | ||
5 | + def send_email | ||
6 | + if user.is_admin?(profile) | ||
7 | + article = Article.find(params[:id]) | ||
8 | + EmailArticlePluginMyprofileController::Sender.content(article).deliver | ||
9 | + render :text => "Email sent to queue" | ||
10 | + else | ||
11 | + render :status => :forbidden, :text => "Forbidden user" | ||
12 | + end | ||
13 | + end | ||
14 | + | ||
15 | + class Sender < ActionMailer::Base | ||
16 | + def content(article) | ||
17 | + members = article.profile.members | ||
18 | + emails = [] | ||
19 | + members.each{ |m| | ||
20 | + emails.push(m.user.email) | ||
21 | + } | ||
22 | + mail( | ||
23 | + content_type: 'text/html', | ||
24 | + to: emails, | ||
25 | + from: "#{article.author.user.name} <#{article.author.user.email}>", | ||
26 | + reply_to: article.author.user.email, | ||
27 | + subject: "[Artigo] " + article.title, | ||
28 | + body: set_absolute_path(article.body, article.environment) | ||
29 | + ) | ||
30 | + end | ||
31 | + | ||
32 | + def set_absolute_path(body, environment) | ||
33 | + parsed = Hpricot(body.to_s) | ||
34 | + parsed.search('img[@src]').map { |i| change_element_path(i, 'src', environment) } | ||
35 | + parsed.search('a[@href]').map { |i| change_element_path(i, 'href', environment) } | ||
36 | + parsed.to_s | ||
37 | + end | ||
38 | + | ||
39 | + def change_element_path(el, attribute, environment) | ||
40 | + fullpath = /^http/.match(el[attribute]) | ||
41 | + if not fullpath | ||
42 | + relative_path = /\/?(.*)/.match(el[attribute]) | ||
43 | + el[attribute] = "http://#{environment.default_hostname}/#{relative_path[1]}" | ||
44 | + end | ||
45 | + end | ||
46 | + end | ||
47 | +end |
@@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
1 | +class EmailArticlePlugin < Noosfero::Plugin | ||
2 | + | ||
3 | + def self.plugin_name | ||
4 | + "Email Article to Community Members Plugin" | ||
5 | + end | ||
6 | + | ||
7 | + def self.plugin_description | ||
8 | + _("A plugin that emails an article to the members of the community") | ||
9 | + end | ||
10 | + | ||
11 | + def article_toolbar_extra_buttons | ||
12 | + label = _("Send article to members") | ||
13 | + htmlclass = _("button with-text icon-menu-mail") | ||
14 | + title = _("Email article to all community members") | ||
15 | + | ||
16 | + proc { | ||
17 | + if !profile.blank? and !user.blank? and user.is_admin?(profile) and @page.kind_of?(TextArticle) | ||
18 | + link_to_remote( | ||
19 | + label, | ||
20 | + { | ||
21 | + :url => { :controller => 'email_article_plugin_myprofile', :action => "send_email", :id => @page}, | ||
22 | + :method => :get, | ||
23 | + :success => "display_notice('" + _("Messages are being sent") + "')", | ||
24 | + :failure => "display_notice('" + _("Error sending emails") + "')", | ||
25 | + :confirm => _("Are you sure you want to email this article to all community members?"), | ||
26 | + }, | ||
27 | + :class => htmlclass, | ||
28 | + :title => title | ||
29 | + ) | ||
30 | + end | ||
31 | + } | ||
32 | + end | ||
33 | +end |
plugins/email_article/test/functional/email_article_plugin_myprofile_controller_test.rb
0 → 100644
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | ||
2 | + | ||
3 | +class EmailArticlePluginMyprofileControllerTest < ActionController::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + Environment.delete_all | ||
7 | + @environment = Environment.new(:name => 'testenv', :is_default => true) | ||
8 | + @environment.enabled_plugins = ['EmailArticlePlugin'] | ||
9 | + @environment.save! | ||
10 | + end | ||
11 | + | ||
12 | + should 'be able to deliver mail as profile admin' do | ||
13 | + @profile = Community.create!(:name => 'Sample community', :identifier => 'sample-community') | ||
14 | + @user = create_user('testinguser') | ||
15 | + login_as(@user.login) | ||
16 | + @profile.add_admin(@user.person) | ||
17 | + @article = @profile.articles.create!(:name => 'a test article', :last_changed_by => @user.person) | ||
18 | + @article.save | ||
19 | + get :send_email, :profile => @profile.identifier, :id => @article.id | ||
20 | + assert_response :success | ||
21 | + end | ||
22 | + | ||
23 | + should 'deny access to email article unless if profile admin' do | ||
24 | + @profile = Community.create!(:name => 'Another community', :identifier => 'another-community') | ||
25 | + @user = create_user('user-out-of-the-community') | ||
26 | + login_as(@user.login) | ||
27 | + @article = @profile.articles.create!(:name => 'a test article', :last_changed_by => @user.person) | ||
28 | + @article.save | ||
29 | + get :send_email, :profile => @profile.identifier, :id => @article.id | ||
30 | + assert_response 403 | ||
31 | + end | ||
32 | + | ||
33 | +end | ||
34 | + | ||
35 | + | ||
36 | + | ||
37 | + | ||
38 | + | ||
39 | + |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../test/test_helper' |
plugins/email_article/test/unit/email_article_plugin_test.rb
0 → 100644
@@ -0,0 +1,21 @@ | @@ -0,0 +1,21 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class EmailArticlePluginTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @plugin = EmailArticlePlugin.new | ||
7 | + end | ||
8 | + | ||
9 | + should 'be a noosfero plugin' do | ||
10 | + assert_kind_of Noosfero::Plugin, @plugin | ||
11 | + end | ||
12 | + | ||
13 | + should 'have name' do | ||
14 | + assert_equal 'Email Article to Community Members Plugin', EmailArticlePlugin.plugin_name | ||
15 | + end | ||
16 | + | ||
17 | + should 'have description' do | ||
18 | + assert_equal _("A plugin that emails an article to the members of the community"), EmailArticlePlugin.plugin_description | ||
19 | + end | ||
20 | + | ||
21 | +end |