Commit 73806727f3564512f7d9de5236ffb1931e0c83d8

Authored by Leandro Santos
Committed by Antonio Terceiro
1 parent 56b351f7

A not logged user can ask to publish an article.

(ActionItem1732)
app/controllers/my_profile/cms_controller.rb
... ... @@ -14,7 +14,8 @@ class CmsController < MyProfileController
14 14 end
15 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 19 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
19 20 end
20 21  
... ... @@ -282,6 +283,18 @@ class CmsController < MyProfileController
282 283 end
283 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 298 def media_listing
286 299 if params[:image_folder_id]
287 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 1177 concat(content_tag('div', wrapper + tag('br', :style => 'clear: both;'), { :class => 'comment-balloon ' + classes.to_s }.merge(options)), block.binding)
1178 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 1189 end
... ...
app/models/suggest_article.rb 0 → 100644
... ... @@ -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
... ...
app/views/cms/suggest_an_article.rhtml 0 → 100644
... ... @@ -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 45 <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %>
46 46 <% end %>
47 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 50 <% end %>
49 51 <div id="article-header">
50 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 91 </div>
90 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 97 # AddThis Button
... ...
app/views/tasks/_suggest_article.rhtml 0 → 100644
... ... @@ -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 @@
  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 5237 .forum-posts .pagination {
5238 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 &lt; Test::Unit::TestCase
1410 1410 assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/upload_files?parent_id=#{profile.forum.id}"}
1411 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 1445 end
... ...
test/functional/tasks_controller_test.rb
... ... @@ -237,4 +237,29 @@ class TasksControllerTest &lt; Test::Unit::TestCase
237 237 assert_equal Task::Status::CANCELLED, task.status
238 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 265 end
... ...
test/unit/suggest_article_test.rb 0 → 100644
... ... @@ -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
... ...