More flexible mail notifications settings at user level. A user has now 3 options:
* notification on any event on all his projects * notification on any event on selected projects only (if the user belongs to more than 1 project) * notification only for things that he watches or he is involded in (eg. issues that he watches or he is author or assignee) git-svn-id: http://redmine.rubyforge.org/svn/trunk@855 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -50,32 +50,44 @@ class MyController < ApplicationController
|
||||
|
||||
# Edit user's account
|
||||
def account
|
||||
@user = self.logged_in_user
|
||||
@user = User.current
|
||||
@pref = @user.pref
|
||||
@user.attributes = params[:user]
|
||||
@user.pref.attributes = params[:pref]
|
||||
if request.post? && @user.save && @user.pref.save
|
||||
flash[:notice] = l(:notice_account_updated)
|
||||
redirect_to :action => 'account'
|
||||
end
|
||||
end
|
||||
|
||||
# Change user's password
|
||||
def change_password
|
||||
@user = self.logged_in_user
|
||||
flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
|
||||
if @user.check_password?(params[:password])
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if request.post?
|
||||
@user.attributes = params[:user]
|
||||
@user.mail_notification = (params[:notification_option] == 'all')
|
||||
@user.pref.attributes = params[:pref]
|
||||
if @user.save
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
else
|
||||
render :action => 'account'
|
||||
@user.pref.save
|
||||
@user.notified_project_ids = (params[:notification_option] == 'selected' ? params[:notified_project_ids] : [])
|
||||
set_language_if_valid @user.language
|
||||
flash[:notice] = l(:notice_account_updated)
|
||||
redirect_to :action => 'account'
|
||||
return
|
||||
end
|
||||
else
|
||||
flash[:error] = l(:notice_account_wrong_password)
|
||||
end
|
||||
redirect_to :action => 'account'
|
||||
@notification_options = [[l(:label_user_mail_option_all), 'all'],
|
||||
[l(:label_user_mail_option_none), 'none']]
|
||||
# Only users that belong to more than 1 project can select projects for which they are notified
|
||||
# Note that @user.membership.size would fail since AR ignores :include association option when doing a count
|
||||
@notification_options.insert 1, [l(:label_user_mail_option_selected), 'selected'] if @user.memberships.length > 1
|
||||
@notification_option = @user.mail_notification? ? 'all' : (@user.notified_projects_ids.empty? ? 'none' : 'selected')
|
||||
end
|
||||
|
||||
# Manage user's password
|
||||
def password
|
||||
@user = self.logged_in_user
|
||||
flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
|
||||
if request.post?
|
||||
if @user.check_password?(params[:password])
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if @user.save
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
redirect_to :action => 'account'
|
||||
end
|
||||
else
|
||||
flash[:error] = l(:notice_account_wrong_password)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create a new feeds key
|
||||
|
||||
@@ -143,6 +143,15 @@ class Issue < ActiveRecord::Base
|
||||
project.assignable_users
|
||||
end
|
||||
|
||||
# Returns the mail adresses of users that should be notified for the issue
|
||||
def recipients
|
||||
recipients = project.recipients
|
||||
# Author and assignee are always notified
|
||||
recipients << author.mail if author
|
||||
recipients << assigned_to.mail if assigned_to
|
||||
recipients.compact.uniq
|
||||
end
|
||||
|
||||
def spent_hours
|
||||
@spent_hours ||= time_entries.sum(:hours) || 0
|
||||
end
|
||||
|
||||
+5
-17
@@ -30,13 +30,7 @@ class Mailer < ActionMailer::Base
|
||||
|
||||
def issue_add(issue)
|
||||
set_language_if_valid(Setting.default_language)
|
||||
# Sends to all project members
|
||||
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
|
||||
# Sends to author and assignee (even if they turned off mail notification)
|
||||
@recipients << issue.author.mail if issue.author
|
||||
@recipients << issue.assigned_to.mail if issue.assigned_to
|
||||
@recipients.compact!
|
||||
@recipients.uniq!
|
||||
@recipients = issue.recipients
|
||||
@from = Setting.mail_from
|
||||
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
|
||||
@body['issue'] = issue
|
||||
@@ -44,14 +38,8 @@ class Mailer < ActionMailer::Base
|
||||
|
||||
def issue_edit(journal)
|
||||
set_language_if_valid(Setting.default_language)
|
||||
# Sends to all project members
|
||||
issue = journal.journalized
|
||||
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
|
||||
# Sends to author and assignee (even if they turned off mail notification)
|
||||
@recipients << issue.author.mail if issue.author
|
||||
@recipients << issue.assigned_to.mail if issue.assigned_to
|
||||
@recipients.compact!
|
||||
@recipients.uniq!
|
||||
@recipients = issue.recipients
|
||||
# Watchers in cc
|
||||
@cc = issue.watcher_recipients - @recipients
|
||||
@from = Setting.mail_from
|
||||
@@ -62,7 +50,7 @@ class Mailer < ActionMailer::Base
|
||||
|
||||
def document_added(document)
|
||||
set_language_if_valid(Setting.default_language)
|
||||
@recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
|
||||
@recipients = document.project.recipients
|
||||
@from = Setting.mail_from
|
||||
@subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
|
||||
@body['document'] = document
|
||||
@@ -81,7 +69,7 @@ class Mailer < ActionMailer::Base
|
||||
url = {:only_path => false, :host => Setting.host_name, :controller => 'documents', :action => 'show', :id => container.id}
|
||||
added_to = "#{l(:label_document)}: #{container.title}"
|
||||
end
|
||||
@recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
|
||||
@recipients = container.project.recipients
|
||||
@from = Setting.mail_from
|
||||
@subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
|
||||
@body['attachments'] = attachments
|
||||
@@ -91,7 +79,7 @@ class Mailer < ActionMailer::Base
|
||||
|
||||
def news_added(news)
|
||||
set_language_if_valid(Setting.default_language)
|
||||
@recipients = news.project.users.collect { |u| u.mail if u.mail_notification }.compact
|
||||
@recipients = news.project.recipients
|
||||
@from = Setting.mail_from
|
||||
@subject = "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
||||
@body['news'] = news
|
||||
|
||||
@@ -118,6 +118,11 @@ class Project < ActiveRecord::Base
|
||||
members.select {|m| m.role.assignable?}.collect {|m| m.user}
|
||||
end
|
||||
|
||||
# Returns the mail adresses of users that should be always notified on project events
|
||||
def recipients
|
||||
members.select {|m| m.mail_notification? || m.user.mail_notification?}.collect {|m| m.user.mail}
|
||||
end
|
||||
|
||||
# Returns an array of all custom fields enabled for project issues
|
||||
# (explictly associated custom fields and custom fields enabled for all projects)
|
||||
def custom_fields_for_issues(tracker)
|
||||
|
||||
@@ -50,6 +50,11 @@ class User < ActiveRecord::Base
|
||||
validates_confirmation_of :password, :allow_nil => true
|
||||
validates_associated :custom_values, :on => :update
|
||||
|
||||
def before_create
|
||||
self.mail_notification = false
|
||||
true
|
||||
end
|
||||
|
||||
def before_save
|
||||
# update hashed_password if password was set
|
||||
self.hashed_password = User.hash_password(self.password) if self.password
|
||||
@@ -131,6 +136,18 @@ class User < ActiveRecord::Base
|
||||
token.value
|
||||
end
|
||||
|
||||
# Return an array of project ids for which the user has explicitly turned mail notifications on
|
||||
def notified_projects_ids
|
||||
@notified_projects_ids ||= memberships.select {|m| m.mail_notification?}.collect(&:project_id)
|
||||
end
|
||||
|
||||
def notified_project_ids=(ids)
|
||||
Member.update_all("mail_notification = #{connection.quoted_false}", ['user_id = ?', id])
|
||||
Member.update_all("mail_notification = #{connection.quoted_true}", ['user_id = ? AND project_id IN (?)', id, ids]) if ids && !ids.empty?
|
||||
@notified_projects_ids = nil
|
||||
notified_projects_ids
|
||||
end
|
||||
|
||||
def self.find_by_rss_key(key)
|
||||
token = Token.find_by_value(key)
|
||||
token && token.user.active? ? token.user : nil
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<h3><%=l(:label_my_account)%></h3>
|
||||
|
||||
<p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
|
||||
<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %></p>
|
||||
<% if @user.rss_token %>
|
||||
<p><%= l(:label_feeds_access_key_created_on, distance_of_time_in_words(Time.now, @user.rss_token.created_on)) %>
|
||||
(<%= link_to l(:button_reset), {:action => 'reset_rss_key'}, :method => :post %>)</p>
|
||||
<% end %>
|
||||
+23
-37
@@ -1,55 +1,41 @@
|
||||
<div class="contextual">
|
||||
<%= link_to(l(:button_change_password), :action => 'password') unless @user.auth_source_id %>
|
||||
</div>
|
||||
<h2><%=l(:label_my_account)%></h2>
|
||||
|
||||
<%= error_messages_for 'user' %>
|
||||
|
||||
<div class="box">
|
||||
<% form_for :user, @user, :url => { :action => "account" }, :builder => TabularFormBuilder, :lang => current_language do |f| %>
|
||||
<div class="splitcontentleft">
|
||||
<h3><%=l(:label_information_plural)%></h3>
|
||||
|
||||
<% labelled_tabular_form_for :user, @user, :url => { :action => "account" } do |f| %>
|
||||
|
||||
<div class="box tabular">
|
||||
<p><%= f.text_field :firstname, :required => true %></p>
|
||||
<p><%= f.text_field :lastname, :required => true %></p>
|
||||
<p><%= f.text_field :mail, :required => true, :size => 40 %></p>
|
||||
<p><%= f.text_field :mail, :required => true %></p>
|
||||
<p><%= f.select :language, lang_options_for_select %></p>
|
||||
<p><%= f.check_box :mail_notification %></p>
|
||||
|
||||
<% fields_for :pref, @user.pref, :builder => TabularFormBuilder, :lang => current_language do |pref_fields| %>
|
||||
<p><%= pref_fields.check_box :hide_mail %></p>
|
||||
<% end %>
|
||||
|
||||
<center><%= submit_tag l(:button_save) %></center>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= submit_tag l(:button_save) %>
|
||||
</div>
|
||||
|
||||
<% unless @user.auth_source_id %>
|
||||
<div class="box">
|
||||
<h3><%=l(:field_password)%></h3>
|
||||
|
||||
<% form_tag({:action => 'change_password'}, :class => "tabular") do %>
|
||||
|
||||
<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'password', nil, :size => 25 %></p>
|
||||
|
||||
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'new_password', nil, :size => 25 %><br />
|
||||
<em><%= l(:text_length_between, 4, 12) %></em></p>
|
||||
|
||||
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
|
||||
|
||||
<center><%= submit_tag l(:button_save) %></center>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="splitcontentright">
|
||||
<h3><%=l(:field_mail_notification)%></h3>
|
||||
<div class="box">
|
||||
<%= select_tag 'notification_option', options_for_select(@notification_options, @notification_option),
|
||||
:onchange => 'if ($("notification_option").value == "selected") {Element.show("notified-projects")} else {Element.hide("notified-projects")}' %>
|
||||
<% content_tag 'div', :id => 'notified-projects', :style => (@notification_option == 'selected' ? '' : 'display:none;') do %>
|
||||
<p><% User.current.projects.each do |project| %>
|
||||
<label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%= project.name %></label><br />
|
||||
<% end %></p>
|
||||
<p><em><%= l(:text_user_mail_option) %></em></p>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<h3><%=l(:label_my_account)%></h3>
|
||||
|
||||
<p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
|
||||
<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %></p>
|
||||
<% if @user.rss_token %>
|
||||
<p><%= l(:label_feeds_access_key_created_on, distance_of_time_in_words(Time.now, @user.rss_token.created_on)) %>
|
||||
(<%= link_to l(:button_reset), {:action => 'reset_rss_key'}, :method => :post %>)</p>
|
||||
<% end %>
|
||||
<%= render :partial => 'sidebar' %>
|
||||
<% end %>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<h2><%=l(:button_change_password)%></h2>
|
||||
|
||||
<%= error_messages_for 'user' %>
|
||||
|
||||
<% form_tag({}, :class => "tabular") do %>
|
||||
<div class="box">
|
||||
<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'password', nil, :size => 25 %></p>
|
||||
|
||||
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'new_password', nil, :size => 25 %><br />
|
||||
<em><%= l(:text_length_between, 4, 12) %></em></p>
|
||||
|
||||
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
|
||||
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
|
||||
</div>
|
||||
<%= submit_tag l(:button_apply) %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= render :partial => 'sidebar' %>
|
||||
<% end %>
|
||||
@@ -14,7 +14,6 @@
|
||||
<% end if @custom_values%>
|
||||
|
||||
<p><%= f.check_box :admin %></p>
|
||||
<p><%= f.check_box :mail_notification %></p>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
|
||||
Reference in New Issue
Block a user