Commit 73806727f3564512f7d9de5236ffb1931e0c83d8
Committed by
Antonio Terceiro
1 parent
56b351f7
Exists in
master
and in
29 other branches
A not logged user can ask to publish an article.
(ActionItem1732)
Showing
11 changed files
with
305 additions
and
10 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -14,7 +14,8 @@ class CmsController < MyProfileController | @@ -14,7 +14,8 @@ class CmsController < MyProfileController | ||
14 | end | 14 | end |
15 | end | 15 | end |
16 | 16 | ||
17 | - protect_if :except => [:set_home_page, :edit, :destroy, :publish] do |c, user, profile| | 17 | + before_filter :login_required, :except => [:suggest_an_article] |
18 | + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish] do |c, user, profile| | ||
18 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) | 19 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) |
19 | end | 20 | end |
20 | 21 | ||
@@ -282,6 +283,18 @@ class CmsController < MyProfileController | @@ -282,6 +283,18 @@ class CmsController < MyProfileController | ||
282 | end | 283 | end |
283 | end | 284 | end |
284 | 285 | ||
286 | + def suggest_an_article | ||
287 | + @back_to = params[:back_to] || request.referer || url_for(profile.public_profile_url) | ||
288 | + @task = SuggestArticle.new(params[:task]) | ||
289 | + if request.post? | ||
290 | + @task.target = profile | ||
291 | + if @task.save | ||
292 | + session[:notice] = _('You make your suggestion successfully. Please wait the article approval.') | ||
293 | + redirect_to @back_to | ||
294 | + end | ||
295 | + end | ||
296 | + end | ||
297 | + | ||
285 | def media_listing | 298 | def media_listing |
286 | if params[:image_folder_id] | 299 | if params[:image_folder_id] |
287 | folder = profile.articles.find(params[:image_folder_id]) if !params[:image_folder_id].blank? | 300 | folder = profile.articles.find(params[:image_folder_id]) if !params[:image_folder_id].blank? |
app/helpers/application_helper.rb
@@ -1177,4 +1177,13 @@ module ApplicationHelper | @@ -1177,4 +1177,13 @@ module ApplicationHelper | ||
1177 | concat(content_tag('div', wrapper + tag('br', :style => 'clear: both;'), { :class => 'comment-balloon ' + classes.to_s }.merge(options)), block.binding) | 1177 | concat(content_tag('div', wrapper + tag('br', :style => 'clear: both;'), { :class => 'comment-balloon ' + classes.to_s }.merge(options)), block.binding) |
1178 | end | 1178 | end |
1179 | 1179 | ||
1180 | + def display_source_info(page) | ||
1181 | + if !page.source.blank? | ||
1182 | + source_url = link_to(page.source_name.blank? ? page.source : page.source_name, page.source) | ||
1183 | + elsif page.reference_article | ||
1184 | + source_url = link_to(page.reference_article.profile.name, page.reference_article.url) | ||
1185 | + end | ||
1186 | + content_tag(:div, _('Source: %s') % source_url, :id => 'article-source') unless source_url.nil? | ||
1187 | + end | ||
1188 | + | ||
1180 | end | 1189 | end |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +class SuggestArticle < Task | ||
2 | + | ||
3 | + has_captcha | ||
4 | + | ||
5 | + serialize :data, Hash | ||
6 | + acts_as_having_settings :field => :data | ||
7 | + | ||
8 | + validates_presence_of :target_id, :article_name, :email, :name, :article_body | ||
9 | + | ||
10 | + def description | ||
11 | + _('%{email} suggested to publish "%{article}" on %{community}') % { :email => email, :article => article_name, :community => target.name } | ||
12 | + end | ||
13 | + | ||
14 | + settings_items :email, :type => String | ||
15 | + settings_items :name, :type => String | ||
16 | + settings_items :article_name, :type => String | ||
17 | + settings_items :article_body, :type => String | ||
18 | + settings_items :article_abstract, :type => String | ||
19 | + settings_items :article_parent_id, :type => String | ||
20 | + settings_items :source, :type => String | ||
21 | + | ||
22 | + def perform | ||
23 | + TinyMceArticle.create!(:profile => target, :name => article_name, :body => article_body, :abstract => article_abstract, :parent_id => article_parent_id, :source => source, :source_name => name) | ||
24 | + end | ||
25 | + | ||
26 | +end |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +<%= error_messages_for 'task' %> | ||
2 | + | ||
3 | +<%= required_fields_message %> | ||
4 | + | ||
5 | +<%= render :file => 'shared/tiny_mce' %> | ||
6 | + | ||
7 | +<% labelled_form_for 'task', @task do |f| %> | ||
8 | + | ||
9 | + <%= required labelled_form_field(_('Title'), text_field(:task, 'article_name')) %> | ||
10 | + | ||
11 | + <%= labelled_form_field(_('Url Source'), text_field(:task, 'source')) %> | ||
12 | + | ||
13 | + <%= required labelled_form_field(_('Name'), text_field(:task, 'name')) %> | ||
14 | + | ||
15 | + <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %> | ||
16 | + | ||
17 | + <br style="clear: both;"/> | ||
18 | + <%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %> | ||
19 | + <em><%= _('Used when a short version your text is needed.') %></em> | ||
20 | + | ||
21 | + <div id="article-lead"> | ||
22 | + <%= labelled_form_field(_('Lead'), text_area(:task , 'article_abstract', :style => 'width: 100%; height: 300px;')) %> | ||
23 | + </div> | ||
24 | + <div style="margin-top: 10px;"> | ||
25 | + <%= labelled_form_field(_('Text'), text_area(:task, 'article_body', :style => 'width:100%')) %> | ||
26 | + </div> | ||
27 | + | ||
28 | + <div id="captcha"> | ||
29 | + <%= labelled_form_field(_("What is the result of '%s = ?'") % @task.captcha.task, text_field(:task, 'captcha_solution')) %> | ||
30 | + <%= hidden_field :task, :captcha_secret %> | ||
31 | + <br style="clear: both;"> | ||
32 | + </div> | ||
33 | + | ||
34 | + <%= hidden_field_tag('back_to', @back_to) %> | ||
35 | + <% button_bar do %> | ||
36 | + <%= submit_button :save, _('Save') %> | ||
37 | + <%= button :cancel, _('Cancel'), @back_to %> | ||
38 | + <% end %> | ||
39 | +<% end %> | ||
40 | + | ||
41 | +<%= javascript_include_tag 'article' %> |
app/views/content_viewer/view_page.rhtml
@@ -45,6 +45,8 @@ | @@ -45,6 +45,8 @@ | ||
45 | <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %> | 45 | <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %> |
46 | <% end %> | 46 | <% end %> |
47 | </div> | 47 | </div> |
48 | + <% else %> | ||
49 | + <%= link_to content_tag( 'span', _('Suggest an article') ), profile.admin_url.merge({ :controller => 'cms', :action => 'suggest_an_article'}), :class => 'button with-text icon-new' %> | ||
48 | <% end %> | 50 | <% end %> |
49 | <div id="article-header"> | 51 | <div id="article-header"> |
50 | <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> | 52 | <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> |
@@ -89,15 +91,7 @@ | @@ -89,15 +91,7 @@ | ||
89 | </div> | 91 | </div> |
90 | <% end %> | 92 | <% end %> |
91 | 93 | ||
92 | -<% if ! @page.source.nil? && ! @page.source.empty?%> | ||
93 | -<div id="article-source"> | ||
94 | - <%= _('Source: %s') % link_to(@page.source, @page.source) %> | ||
95 | -</div> | ||
96 | -<% elsif @page.reference_article %> | ||
97 | -<div id="article-source"> | ||
98 | - <%= _('Source: %s') % link_to(@page.reference_article.profile.name, @page.reference_article.url) %> | ||
99 | -</div> | ||
100 | -<% end %> | 94 | +<%= display_source_info(@page) %> |
101 | 95 | ||
102 | <% | 96 | <% |
103 | # AddThis Button | 97 | # AddThis Button |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +<h2><%= _('Processing task: %s') % task.description %></h2> | ||
2 | + | ||
3 | +<%= render :file => 'shared/tiny_mce' %> | ||
4 | + | ||
5 | +<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %> | ||
6 | + | ||
7 | + <p> <%= label_tag(_("Sent by: %s") % task.name) %> </p> | ||
8 | + <p><%= label_tag(_("Email: %s") % task.email) %> </p> | ||
9 | + <p><%= label_tag(_("Source: %s") % task.source) %> </p> | ||
10 | + | ||
11 | + <%= required labelled_form_field(_('Title'), text_field_tag('task[article_name]', task.article_name)) %> | ||
12 | + | ||
13 | + <%= select_folder(_('Select the folder where the article must be published'), 'task', 'article_parent_id', task.target.folders) %> | ||
14 | + | ||
15 | + | ||
16 | + <br style="clear: both;"/> | ||
17 | + <%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %> | ||
18 | + <em><%= _('Used when a short version your text is needed.') %></em> | ||
19 | + | ||
20 | + <div id="article-lead"> | ||
21 | + <%= labelled_form_field(_('Lead'), text_area_tag('task[article_abstract]', task.article_abstract, :style => 'width: 100%; height: 300px;')) %> | ||
22 | + </div> | ||
23 | + <div style="margin-top: 10px;"> | ||
24 | + <%= labelled_form_field(_('Text'), text_area_tag('task[article_body]', task.article_body, :style => 'width:100%')) %> | ||
25 | + </div> | ||
26 | + | ||
27 | + <div> | ||
28 | + <%= labelled_radio_button _('OK'), :decision, 'finish', true, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='none'" %> | ||
29 | + </div> | ||
30 | + <div> | ||
31 | + <%= labelled_radio_button _('Cancel'), :decision, 'cancel', false, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='block'" %> | ||
32 | + </div> | ||
33 | + | ||
34 | + <% button_bar do %> | ||
35 | + <%= submit_button(:ok, _('OK')) %> | ||
36 | + <% end %> | ||
37 | + | ||
38 | +<% end %> | ||
39 | + | ||
40 | +<%= javascript_include_tag 'article' %> | ||
41 | + |
db/migrate/20101209001631_add_source_name_to_articles.rb
0 → 100644
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +class AddSourceNameToArticles < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + add_column :articles, :source_name, :string, :null => true | ||
4 | + add_column :article_versions, :source_name, :string, :null => true | ||
5 | + end | ||
6 | + | ||
7 | + def self.down | ||
8 | + remove_column :articles, :source_name | ||
9 | + remove_column :article_versions, :source_name | ||
10 | + end | ||
11 | +end |
public/stylesheets/application.css
@@ -5237,3 +5237,17 @@ h1#agenda-title { | @@ -5237,3 +5237,17 @@ h1#agenda-title { | ||
5237 | .forum-posts .pagination { | 5237 | .forum-posts .pagination { |
5238 | margin-top: 20px; | 5238 | margin-top: 20px; |
5239 | } | 5239 | } |
5240 | + | ||
5241 | +#captcha input { | ||
5242 | + border: 1px solid #ccc; | ||
5243 | + margin: 4px 0px 2px 10px !important; | ||
5244 | + padding: 0px !important; | ||
5245 | + width: 150px !important; | ||
5246 | + font-size: 24px; | ||
5247 | + float: left; | ||
5248 | +} | ||
5249 | + | ||
5250 | +#captcha label{ | ||
5251 | + float: left; | ||
5252 | + font-size: 24px; | ||
5253 | +} |
test/functional/cms_controller_test.rb
@@ -1410,4 +1410,36 @@ class CmsControllerTest < Test::Unit::TestCase | @@ -1410,4 +1410,36 @@ class CmsControllerTest < Test::Unit::TestCase | ||
1410 | assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/upload_files?parent_id=#{profile.forum.id}"} | 1410 | assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/upload_files?parent_id=#{profile.forum.id}"} |
1411 | end | 1411 | end |
1412 | 1412 | ||
1413 | + should 'not logged in to suggest an article' do | ||
1414 | + logout | ||
1415 | + get :suggest_an_article, :profile => profile.identifier, :back_to => 'action_view' | ||
1416 | + | ||
1417 | + assert_template 'suggest_an_article' | ||
1418 | + end | ||
1419 | + | ||
1420 | + should 'create a task suggest task to a profile' do | ||
1421 | + c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | ||
1422 | + | ||
1423 | + SuggestArticle.any_instance.stubs(:skip_captcha?).returns(true) | ||
1424 | + assert_difference SuggestArticle, :count do | ||
1425 | + post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article_name => 'some name', :article_body => 'some body', :email => 'some@localhost.com', :name => 'some name'} | ||
1426 | + end | ||
1427 | + end | ||
1428 | + | ||
1429 | + should 'suggest an article from a profile' do | ||
1430 | + c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | ||
1431 | + get :suggest_an_article, :profile => c.identifier, :back_to => c.identifier | ||
1432 | + assert_response :success | ||
1433 | + assert_template 'suggest_an_article' | ||
1434 | + assert_tag :tag => 'input', :attributes => { :value => c.identifier, :id => 'back_to' } | ||
1435 | + end | ||
1436 | + | ||
1437 | + should 'suggest an article accessing the url directly' do | ||
1438 | + c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) | ||
1439 | + get :suggest_an_article, :profile => c.identifier | ||
1440 | + assert_response :success | ||
1441 | + assert_template 'suggest_an_article' | ||
1442 | + assert_tag :tag => 'input', :attributes => { :value => "https://colivre.net/profile/test_comm", :id => 'back_to' } | ||
1443 | + end | ||
1444 | + | ||
1413 | end | 1445 | end |
test/functional/tasks_controller_test.rb
@@ -237,4 +237,29 @@ class TasksControllerTest < Test::Unit::TestCase | @@ -237,4 +237,29 @@ class TasksControllerTest < Test::Unit::TestCase | ||
237 | assert_equal Task::Status::CANCELLED, task.status | 237 | assert_equal Task::Status::CANCELLED, task.status |
238 | end | 238 | end |
239 | 239 | ||
240 | + should 'create TinyMceArticle article after finish approve suggested article task' do | ||
241 | + TinyMceArticle.destroy_all | ||
242 | + c = fast_create(Community) | ||
243 | + c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) | ||
244 | + @controller.stubs(:profile).returns(c) | ||
245 | + SuggestArticle.skip_captcha! | ||
246 | + t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) | ||
247 | + | ||
248 | + post :close, :decision => 'finish', :id => t.id, :task => {} | ||
249 | + assert_not_nil TinyMceArticle.find(:first) | ||
250 | + end | ||
251 | + | ||
252 | + should "change the article's attributes on suggested article task approval" do | ||
253 | + TinyMceArticle.destroy_all | ||
254 | + c = fast_create(Community) | ||
255 | + c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) | ||
256 | + @controller.stubs(:profile).returns(c) | ||
257 | + SuggestArticle.skip_captcha! | ||
258 | + t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) | ||
259 | + | ||
260 | + post :close, :decision => 'finish', :id => t.id, :task => {:article_name => 'new name', :article_body => 'new body'} | ||
261 | + assert_equal 'new name', TinyMceArticle.find(:first).name | ||
262 | + assert_equal 'new body', TinyMceArticle.find(:first).body | ||
263 | + end | ||
264 | + | ||
240 | end | 265 | end |
@@ -0,0 +1,89 @@ | @@ -0,0 +1,89 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class SuggestArticleTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + ActionMailer::Base.delivery_method = :test | ||
7 | + ActionMailer::Base.perform_deliveries = true | ||
8 | + ActionMailer::Base.deliveries = [] | ||
9 | + @profile = create_user('test_user').person | ||
10 | + end | ||
11 | + attr_reader :profile | ||
12 | + | ||
13 | + should 'have the article_name' do | ||
14 | + t = SuggestArticle.new | ||
15 | + assert !t.errors.invalid?(:article_name) | ||
16 | + t.valid? | ||
17 | + assert t.errors.invalid?(:article_name) | ||
18 | + end | ||
19 | + | ||
20 | + should 'have the article_body' do | ||
21 | + t = SuggestArticle.new | ||
22 | + assert !t.errors.invalid?(:article_body) | ||
23 | + t.valid? | ||
24 | + assert t.errors.invalid?(:article_body) | ||
25 | + end | ||
26 | + | ||
27 | + should 'have the email' do | ||
28 | + t = SuggestArticle.new | ||
29 | + assert !t.errors.invalid?(:email) | ||
30 | + t.valid? | ||
31 | + assert t.errors.invalid?(:email) | ||
32 | + end | ||
33 | + | ||
34 | + should 'have the name' do | ||
35 | + t = SuggestArticle.new | ||
36 | + assert !t.errors.invalid?(:name) | ||
37 | + t.valid? | ||
38 | + assert t.errors.invalid?(:name) | ||
39 | + end | ||
40 | + | ||
41 | + should 'have the target_id' do | ||
42 | + t = SuggestArticle.new | ||
43 | + assert !t.errors.invalid?(:target_id) | ||
44 | + t.valid? | ||
45 | + assert t.errors.invalid?(:target_id) | ||
46 | + end | ||
47 | + | ||
48 | + should 'have the captcha_solution be solved' do | ||
49 | + t = SuggestArticle.new | ||
50 | + assert !t.errors.invalid?(:captcha_solution) | ||
51 | + t.valid? | ||
52 | + assert t.errors.invalid?(:captcha_solution) | ||
53 | + | ||
54 | + t.skip_captcha! | ||
55 | + assert t.skip_captcha? | ||
56 | + t.valid? | ||
57 | + assert !t.errors.invalid?(:captcha_solution) | ||
58 | + end | ||
59 | + | ||
60 | + should 'have the article_abstract' do | ||
61 | + t = SuggestArticle.new | ||
62 | + assert t.respond_to?(:article_abstract) | ||
63 | + end | ||
64 | + | ||
65 | + should 'have the article_parent_id' do | ||
66 | + t = SuggestArticle.new | ||
67 | + assert t.respond_to?(:article_parent_id) | ||
68 | + end | ||
69 | + | ||
70 | + should 'source be defined' do | ||
71 | + t = SuggestArticle.new | ||
72 | + assert t.respond_to?(:source) | ||
73 | + end | ||
74 | + | ||
75 | + should 'create an article on with perfom method' do | ||
76 | + t = SuggestArticle.new | ||
77 | + name = 'some name' | ||
78 | + body = 'some body' | ||
79 | + abstract = 'some abstract' | ||
80 | + t.article_name = name | ||
81 | + t.article_body = body | ||
82 | + t.article_abstract = abstract | ||
83 | + t.target = @profile | ||
84 | + count = TinyMceArticle.count | ||
85 | + t.perform | ||
86 | + assert_equal count + 1, TinyMceArticle.count | ||
87 | + end | ||
88 | + | ||
89 | +end |