Adds email notifications support for news comments (#2074).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5003 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
2fa11b2168
commit
6f5707c2b5
@ -1,5 +1,5 @@
|
|||||||
# redMine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -25,6 +25,8 @@ class NewsController < ApplicationController
|
|||||||
before_filter :find_optional_project, :only => :index
|
before_filter :find_optional_project, :only => :index
|
||||||
accept_key_auth :index
|
accept_key_auth :index
|
||||||
|
|
||||||
|
helper :watchers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
case params[:format]
|
case params[:format]
|
||||||
when 'xml', 'json'
|
when 'xml', 'json'
|
||||||
|
24
app/models/comment_observer.rb
Normal file
24
app/models/comment_observer.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Redmine - project management software
|
||||||
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class CommentObserver < ActiveRecord::Observer
|
||||||
|
def after_create(comment)
|
||||||
|
if comment.commented.is_a?(News) && Setting.notified_events.include?('news_comment_added')
|
||||||
|
Mailer.deliver_news_comment_added(comment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -1,5 +1,5 @@
|
|||||||
# redMine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -154,6 +154,24 @@ class Mailer < ActionMailer::Base
|
|||||||
:news_url => url_for(:controller => 'news', :action => 'show', :id => news)
|
:news_url => url_for(:controller => 'news', :action => 'show', :id => news)
|
||||||
render_multipart('news_added', body)
|
render_multipart('news_added', body)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Builds a tmail object used to email recipients of a news' project when a news comment is added.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# news_comment_added(comment) => tmail object
|
||||||
|
# Mailer.news_comment_added(comment) => sends an email to the news' project recipients
|
||||||
|
def news_comment_added(comment)
|
||||||
|
news = comment.commented
|
||||||
|
redmine_headers 'Project' => news.project.identifier
|
||||||
|
message_id comment
|
||||||
|
recipients news.recipients
|
||||||
|
cc news.watcher_recipients
|
||||||
|
subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
||||||
|
body :news => news,
|
||||||
|
:comment => comment,
|
||||||
|
:news_url => url_for(:controller => 'news', :action => 'show', :id => news)
|
||||||
|
render_multipart('news_comment_added', body)
|
||||||
|
end
|
||||||
|
|
||||||
# Builds a tmail object used to email the recipients of the specified message that was posted.
|
# Builds a tmail object used to email the recipients of the specified message that was posted.
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Redmine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -28,6 +28,9 @@ class News < ActiveRecord::Base
|
|||||||
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
|
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
|
||||||
acts_as_activity_provider :find_options => {:include => [:project, :author]},
|
acts_as_activity_provider :find_options => {:include => [:project, :author]},
|
||||||
:author_key => :author_id
|
:author_key => :author_id
|
||||||
|
acts_as_watchable
|
||||||
|
|
||||||
|
after_create :add_author_as_watcher
|
||||||
|
|
||||||
named_scope :visible, lambda {|*args| {
|
named_scope :visible, lambda {|*args| {
|
||||||
:include => :project,
|
:include => :project,
|
||||||
@ -42,4 +45,10 @@ class News < ActiveRecord::Base
|
|||||||
def self.latest(user = User.current, count = 5)
|
def self.latest(user = User.current, count = 5)
|
||||||
find(:all, :limit => count, :conditions => Project.allowed_to_condition(user, :view_news), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
find(:all, :limit => count, :conditions => Project.allowed_to_condition(user, :view_news), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def add_author_as_watcher
|
||||||
|
Watcher.create(:watchable => self, :user => author)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
5
app/views/mailer/news_comment_added.text.html.rhtml
Normal file
5
app/views/mailer/news_comment_added.text.html.rhtml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<h1><%= link_to(h(@news.title), @news_url) %></h1>
|
||||||
|
|
||||||
|
<p><%= l(:text_user_wrote, :value => h(@comment.author)) %></p>
|
||||||
|
|
||||||
|
<%= textilizable @comment, :comments, :only_path => false %>
|
6
app/views/mailer/news_comment_added.text.plain.rhtml
Normal file
6
app/views/mailer/news_comment_added.text.plain.rhtml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<%= @news.title %>
|
||||||
|
<%= @news_url %>
|
||||||
|
|
||||||
|
<%= l(:text_user_wrote, :value => @comment.author) %>
|
||||||
|
|
||||||
|
<%= @comment.comments %>
|
@ -1,4 +1,5 @@
|
|||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
|
<%= watcher_tag(@news, User.current) %>
|
||||||
<%= link_to(l(:button_edit),
|
<%= link_to(l(:button_edit),
|
||||||
edit_news_path(@news),
|
edit_news_path(@news),
|
||||||
:class => 'icon icon-edit',
|
:class => 'icon icon-edit',
|
||||||
|
@ -36,7 +36,7 @@ Rails::Initializer.run do |config|
|
|||||||
|
|
||||||
# Activate observers that should always be running
|
# Activate observers that should always be running
|
||||||
# config.active_record.observers = :cacher, :garbage_collector
|
# config.active_record.observers = :cacher, :garbage_collector
|
||||||
config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer
|
config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer, :comment_observer
|
||||||
|
|
||||||
# Make Active Record use UTC-base instead of local time
|
# Make Active Record use UTC-base instead of local time
|
||||||
# config.active_record.default_timezone = :utc
|
# config.active_record.default_timezone = :utc
|
||||||
|
@ -537,6 +537,7 @@ en:
|
|||||||
label_news_latest: Latest news
|
label_news_latest: Latest news
|
||||||
label_news_view_all: View all news
|
label_news_view_all: View all news
|
||||||
label_news_added: News added
|
label_news_added: News added
|
||||||
|
label_news_comment_added: Comment added to a news
|
||||||
label_settings: Settings
|
label_settings: Settings
|
||||||
label_overview: Overview
|
label_overview: Overview
|
||||||
label_version: Version
|
label_version: Version
|
||||||
|
@ -539,6 +539,7 @@ fr:
|
|||||||
label_news_latest: Dernières annonces
|
label_news_latest: Dernières annonces
|
||||||
label_news_view_all: Voir toutes les annonces
|
label_news_view_all: Voir toutes les annonces
|
||||||
label_news_added: Annonce ajoutée
|
label_news_added: Annonce ajoutée
|
||||||
|
label_news_comment_added: Commentaire ajouté à une annonce
|
||||||
label_settings: Configuration
|
label_settings: Configuration
|
||||||
label_overview: Aperçu
|
label_overview: Aperçu
|
||||||
label_version: Version
|
label_version: Version
|
||||||
|
@ -14,6 +14,7 @@ module Redmine
|
|||||||
notifications << Notifiable.new('issue_status_updated', 'issue_updated')
|
notifications << Notifiable.new('issue_status_updated', 'issue_updated')
|
||||||
notifications << Notifiable.new('issue_priority_updated', 'issue_updated')
|
notifications << Notifiable.new('issue_priority_updated', 'issue_updated')
|
||||||
notifications << Notifiable.new('news_added')
|
notifications << Notifiable.new('news_added')
|
||||||
|
notifications << Notifiable.new('news_comment_added')
|
||||||
notifications << Notifiable.new('document_added')
|
notifications << Notifiable.new('document_added')
|
||||||
notifications << Notifiable.new('file_added')
|
notifications << Notifiable.new('file_added')
|
||||||
notifications << Notifiable.new('message_posted')
|
notifications << Notifiable.new('message_posted')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# redMine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -31,6 +31,15 @@ class CommentTest < ActiveSupport::TestCase
|
|||||||
@news.reload
|
@news.reload
|
||||||
assert_equal 2, @news.comments_count
|
assert_equal 2, @news.comments_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_create_should_send_notification
|
||||||
|
Setting.notified_events << 'news_comment_added'
|
||||||
|
Watcher.create!(:watchable => @news, :user => @jsmith)
|
||||||
|
|
||||||
|
assert_difference 'ActionMailer::Base.deliveries.size' do
|
||||||
|
Comment.create!(:commented => @news, :author => @jsmith, :comments => "my comment")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_validate
|
def test_validate
|
||||||
comment = Comment.new(:commented => @news)
|
comment = Comment.new(:commented => @news)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# redMine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -22,9 +22,9 @@ class Redmine::NotifiableTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_all
|
def test_all
|
||||||
assert_equal 11, Redmine::Notifiable.all.length
|
assert_equal 12, Redmine::Notifiable.all.length
|
||||||
|
|
||||||
%w(issue_added issue_updated issue_note_added issue_status_updated issue_priority_updated news_added document_added file_added message_posted wiki_content_added wiki_content_updated).each do |notifiable|
|
%w(issue_added issue_updated issue_note_added issue_status_updated issue_priority_updated news_added news_comment_added document_added file_added message_posted wiki_content_added wiki_content_updated).each do |notifiable|
|
||||||
assert Redmine::Notifiable.all.collect(&:name).include?(notifiable), "missing #{notifiable}"
|
assert Redmine::Notifiable.all.collect(&:name).include?(notifiable), "missing #{notifiable}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# redMine - project management software
|
# Redmine - project management software
|
||||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
# Copyright (C) 2006-2011 Jean-Philippe Lang
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
|||||||
class MailerTest < ActiveSupport::TestCase
|
class MailerTest < ActiveSupport::TestCase
|
||||||
include Redmine::I18n
|
include Redmine::I18n
|
||||||
include ActionController::Assertions::SelectorAssertions
|
include ActionController::Assertions::SelectorAssertions
|
||||||
fixtures :projects, :enabled_modules, :issues, :users, :members, :member_roles, :roles, :documents, :attachments, :news, :tokens, :journals, :journal_details, :changesets, :trackers, :issue_statuses, :enumerations, :messages, :boards, :repositories
|
fixtures :all
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
@ -295,6 +295,14 @@ class MailerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_news_comment_added
|
||||||
|
comment = Comment.find(2)
|
||||||
|
valid_languages.each do |lang|
|
||||||
|
Setting.default_language = lang.to_s
|
||||||
|
assert Mailer.deliver_news_comment_added(comment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_message_posted
|
def test_message_posted
|
||||||
message = Message.find(:first)
|
message = Message.find(:first)
|
||||||
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
|
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user