##// END OF EJS Templates
Slight changes to ease Rails 2.2 support....
Jean-Philippe Lang -
r2232:260373aed71e
parent child
Show More
@@ -0,0 +1,38
1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine
19 module Utils
20 class << self
21 # Returns the relative root url of the application
22 def relative_url_root
23 ActionController::Base.respond_to?('relative_url_root') ?
24 ActionController::Base.relative_url_root.to_s :
25 ActionController::AbstractRequest.relative_url_root.to_s
26 end
27
28 # Sets the relative root url of the application
29 def relative_url_root=(arg)
30 if ActionController::Base.respond_to?('relative_url_root=')
31 ActionController::Base.relative_url_root=arg
32 else
33 ActionController::AbstractRequest.relative_url_root=arg
34 end
35 end
36 end
37 end
38 end
@@ -1,59 +1,59
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class SettingsController < ApplicationController
18 class SettingsController < ApplicationController
19 before_filter :require_admin
19 before_filter :require_admin
20
20
21 def index
21 def index
22 edit
22 edit
23 render :action => 'edit'
23 render :action => 'edit'
24 end
24 end
25
25
26 def edit
26 def edit
27 @notifiables = %w(issue_added issue_updated news_added document_added file_added message_posted)
27 @notifiables = %w(issue_added issue_updated news_added document_added file_added message_posted)
28 if request.post? && params[:settings] && params[:settings].is_a?(Hash)
28 if request.post? && params[:settings] && params[:settings].is_a?(Hash)
29 settings = (params[:settings] || {}).dup.symbolize_keys
29 settings = (params[:settings] || {}).dup.symbolize_keys
30 settings.each do |name, value|
30 settings.each do |name, value|
31 # remove blank values in array settings
31 # remove blank values in array settings
32 value.delete_if {|v| v.blank? } if value.is_a?(Array)
32 value.delete_if {|v| v.blank? } if value.is_a?(Array)
33 Setting[name] = value
33 Setting[name] = value
34 end
34 end
35 flash[:notice] = l(:notice_successful_update)
35 flash[:notice] = l(:notice_successful_update)
36 redirect_to :action => 'edit', :tab => params[:tab]
36 redirect_to :action => 'edit', :tab => params[:tab]
37 return
37 return
38 end
38 end
39 @options = {}
39 @options = {}
40 @options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
40 @options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
41 @deliveries = ActionMailer::Base.perform_deliveries
41 @deliveries = ActionMailer::Base.perform_deliveries
42
42
43 @guessed_host_and_path = request.host_with_port
43 @guessed_host_and_path = request.host_with_port
44 @guessed_host_and_path << ('/'+ request.relative_url_root.gsub(%r{^\/}, '')) unless request.relative_url_root.blank?
44 @guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
45 end
45 end
46
46
47 def plugin
47 def plugin
48 @plugin = Redmine::Plugin.find(params[:id])
48 @plugin = Redmine::Plugin.find(params[:id])
49 if request.post?
49 if request.post?
50 Setting["plugin_#{@plugin.id}"] = params[:settings]
50 Setting["plugin_#{@plugin.id}"] = params[:settings]
51 flash[:notice] = l(:notice_successful_update)
51 flash[:notice] = l(:notice_successful_update)
52 redirect_to :action => 'plugin', :id => @plugin.id
52 redirect_to :action => 'plugin', :id => @plugin.id
53 end
53 end
54 @partial = @plugin.settings[:partial]
54 @partial = @plugin.settings[:partial]
55 @settings = Setting["plugin_#{@plugin.id}"]
55 @settings = Setting["plugin_#{@plugin.id}"]
56 rescue Redmine::PluginNotFound
56 rescue Redmine::PluginNotFound
57 render_404
57 render_404
58 end
58 end
59 end
59 end
@@ -1,253 +1,253
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Mailer < ActionMailer::Base
18 class Mailer < ActionMailer::Base
19 helper :application
19 helper :application
20 helper :issues
20 helper :issues
21 helper :custom_fields
21 helper :custom_fields
22
22
23 include ActionController::UrlWriter
23 include ActionController::UrlWriter
24
24
25 def issue_add(issue)
25 def issue_add(issue)
26 redmine_headers 'Project' => issue.project.identifier,
26 redmine_headers 'Project' => issue.project.identifier,
27 'Issue-Id' => issue.id,
27 'Issue-Id' => issue.id,
28 'Issue-Author' => issue.author.login
28 'Issue-Author' => issue.author.login
29 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
29 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
30 recipients issue.recipients
30 recipients issue.recipients
31 cc(issue.watcher_recipients - @recipients)
31 cc(issue.watcher_recipients - @recipients)
32 subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
32 subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
33 body :issue => issue,
33 body :issue => issue,
34 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
34 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
35 end
35 end
36
36
37 def issue_edit(journal)
37 def issue_edit(journal)
38 issue = journal.journalized
38 issue = journal.journalized
39 redmine_headers 'Project' => issue.project.identifier,
39 redmine_headers 'Project' => issue.project.identifier,
40 'Issue-Id' => issue.id,
40 'Issue-Id' => issue.id,
41 'Issue-Author' => issue.author.login
41 'Issue-Author' => issue.author.login
42 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
42 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
43 @author = journal.user
43 @author = journal.user
44 recipients issue.recipients
44 recipients issue.recipients
45 # Watchers in cc
45 # Watchers in cc
46 cc(issue.watcher_recipients - @recipients)
46 cc(issue.watcher_recipients - @recipients)
47 s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
47 s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
48 s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
48 s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
49 s << issue.subject
49 s << issue.subject
50 subject s
50 subject s
51 body :issue => issue,
51 body :issue => issue,
52 :journal => journal,
52 :journal => journal,
53 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
53 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
54 end
54 end
55
55
56 def reminder(user, issues, days)
56 def reminder(user, issues, days)
57 set_language_if_valid user.language
57 set_language_if_valid user.language
58 recipients user.mail
58 recipients user.mail
59 subject l(:mail_subject_reminder, issues.size)
59 subject l(:mail_subject_reminder, issues.size)
60 body :issues => issues,
60 body :issues => issues,
61 :days => days,
61 :days => days,
62 :issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'due_date', :sort_order => 'asc')
62 :issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'due_date', :sort_order => 'asc')
63 end
63 end
64
64
65 def document_added(document)
65 def document_added(document)
66 redmine_headers 'Project' => document.project.identifier
66 redmine_headers 'Project' => document.project.identifier
67 recipients document.project.recipients
67 recipients document.project.recipients
68 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
68 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
69 body :document => document,
69 body :document => document,
70 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
70 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
71 end
71 end
72
72
73 def attachments_added(attachments)
73 def attachments_added(attachments)
74 container = attachments.first.container
74 container = attachments.first.container
75 added_to = ''
75 added_to = ''
76 added_to_url = ''
76 added_to_url = ''
77 case container.class.name
77 case container.class.name
78 when 'Project'
78 when 'Project'
79 added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container)
79 added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container)
80 added_to = "#{l(:label_project)}: #{container}"
80 added_to = "#{l(:label_project)}: #{container}"
81 when 'Version'
81 when 'Version'
82 added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container.project_id)
82 added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container.project_id)
83 added_to = "#{l(:label_version)}: #{container.name}"
83 added_to = "#{l(:label_version)}: #{container.name}"
84 when 'Document'
84 when 'Document'
85 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
85 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
86 added_to = "#{l(:label_document)}: #{container.title}"
86 added_to = "#{l(:label_document)}: #{container.title}"
87 end
87 end
88 redmine_headers 'Project' => container.project.identifier
88 redmine_headers 'Project' => container.project.identifier
89 recipients container.project.recipients
89 recipients container.project.recipients
90 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
90 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
91 body :attachments => attachments,
91 body :attachments => attachments,
92 :added_to => added_to,
92 :added_to => added_to,
93 :added_to_url => added_to_url
93 :added_to_url => added_to_url
94 end
94 end
95
95
96 def news_added(news)
96 def news_added(news)
97 redmine_headers 'Project' => news.project.identifier
97 redmine_headers 'Project' => news.project.identifier
98 recipients news.project.recipients
98 recipients news.project.recipients
99 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
99 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
100 body :news => news,
100 body :news => news,
101 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
101 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
102 end
102 end
103
103
104 def message_posted(message, recipients)
104 def message_posted(message, recipients)
105 redmine_headers 'Project' => message.project.identifier,
105 redmine_headers 'Project' => message.project.identifier,
106 'Topic-Id' => (message.parent_id || message.id)
106 'Topic-Id' => (message.parent_id || message.id)
107 recipients(recipients)
107 recipients(recipients)
108 subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}"
108 subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}"
109 body :message => message,
109 body :message => message,
110 :message_url => url_for(:controller => 'messages', :action => 'show', :board_id => message.board_id, :id => message.root)
110 :message_url => url_for(:controller => 'messages', :action => 'show', :board_id => message.board_id, :id => message.root)
111 end
111 end
112
112
113 def account_information(user, password)
113 def account_information(user, password)
114 set_language_if_valid user.language
114 set_language_if_valid user.language
115 recipients user.mail
115 recipients user.mail
116 subject l(:mail_subject_register, Setting.app_title)
116 subject l(:mail_subject_register, Setting.app_title)
117 body :user => user,
117 body :user => user,
118 :password => password,
118 :password => password,
119 :login_url => url_for(:controller => 'account', :action => 'login')
119 :login_url => url_for(:controller => 'account', :action => 'login')
120 end
120 end
121
121
122 def account_activation_request(user)
122 def account_activation_request(user)
123 # Send the email to all active administrators
123 # Send the email to all active administrators
124 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
124 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
125 subject l(:mail_subject_account_activation_request, Setting.app_title)
125 subject l(:mail_subject_account_activation_request, Setting.app_title)
126 body :user => user,
126 body :user => user,
127 :url => url_for(:controller => 'users', :action => 'index', :status => User::STATUS_REGISTERED, :sort_key => 'created_on', :sort_order => 'desc')
127 :url => url_for(:controller => 'users', :action => 'index', :status => User::STATUS_REGISTERED, :sort_key => 'created_on', :sort_order => 'desc')
128 end
128 end
129
129
130 def lost_password(token)
130 def lost_password(token)
131 set_language_if_valid(token.user.language)
131 set_language_if_valid(token.user.language)
132 recipients token.user.mail
132 recipients token.user.mail
133 subject l(:mail_subject_lost_password, Setting.app_title)
133 subject l(:mail_subject_lost_password, Setting.app_title)
134 body :token => token,
134 body :token => token,
135 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
135 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
136 end
136 end
137
137
138 def register(token)
138 def register(token)
139 set_language_if_valid(token.user.language)
139 set_language_if_valid(token.user.language)
140 recipients token.user.mail
140 recipients token.user.mail
141 subject l(:mail_subject_register, Setting.app_title)
141 subject l(:mail_subject_register, Setting.app_title)
142 body :token => token,
142 body :token => token,
143 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
143 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
144 end
144 end
145
145
146 def test(user)
146 def test(user)
147 set_language_if_valid(user.language)
147 set_language_if_valid(user.language)
148 recipients user.mail
148 recipients user.mail
149 subject 'Redmine test'
149 subject 'Redmine test'
150 body :url => url_for(:controller => 'welcome')
150 body :url => url_for(:controller => 'welcome')
151 end
151 end
152
152
153 # Overrides default deliver! method to prevent from sending an email
153 # Overrides default deliver! method to prevent from sending an email
154 # with no recipient, cc or bcc
154 # with no recipient, cc or bcc
155 def deliver!(mail = @mail)
155 def deliver!(mail = @mail)
156 return false if (recipients.nil? || recipients.empty?) &&
156 return false if (recipients.nil? || recipients.empty?) &&
157 (cc.nil? || cc.empty?) &&
157 (cc.nil? || cc.empty?) &&
158 (bcc.nil? || bcc.empty?)
158 (bcc.nil? || bcc.empty?)
159 super
159 super
160 end
160 end
161
161
162 # Sends reminders to issue assignees
162 # Sends reminders to issue assignees
163 # Available options:
163 # Available options:
164 # * :days => how many days in the future to remind about (defaults to 7)
164 # * :days => how many days in the future to remind about (defaults to 7)
165 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
165 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
166 # * :project => id or identifier of project to process (defaults to all projects)
166 # * :project => id or identifier of project to process (defaults to all projects)
167 def self.reminders(options={})
167 def self.reminders(options={})
168 days = options[:days] || 7
168 days = options[:days] || 7
169 project = options[:project] ? Project.find(options[:project]) : nil
169 project = options[:project] ? Project.find(options[:project]) : nil
170 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
170 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
171
171
172 s = ARCondition.new ["#{IssueStatus.table_name}.is_closed = ? AND #{Issue.table_name}.due_date <= ?", false, days.day.from_now.to_date]
172 s = ARCondition.new ["#{IssueStatus.table_name}.is_closed = ? AND #{Issue.table_name}.due_date <= ?", false, days.day.from_now.to_date]
173 s << "#{Issue.table_name}.assigned_to_id IS NOT NULL"
173 s << "#{Issue.table_name}.assigned_to_id IS NOT NULL"
174 s << "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}"
174 s << "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}"
175 s << "#{Issue.table_name}.project_id = #{project.id}" if project
175 s << "#{Issue.table_name}.project_id = #{project.id}" if project
176 s << "#{Issue.table_name}.tracker_id = #{tracker.id}" if tracker
176 s << "#{Issue.table_name}.tracker_id = #{tracker.id}" if tracker
177
177
178 issues_by_assignee = Issue.find(:all, :include => [:status, :assigned_to, :project, :tracker],
178 issues_by_assignee = Issue.find(:all, :include => [:status, :assigned_to, :project, :tracker],
179 :conditions => s.conditions
179 :conditions => s.conditions
180 ).group_by(&:assigned_to)
180 ).group_by(&:assigned_to)
181 issues_by_assignee.each do |assignee, issues|
181 issues_by_assignee.each do |assignee, issues|
182 deliver_reminder(assignee, issues, days) unless assignee.nil?
182 deliver_reminder(assignee, issues, days) unless assignee.nil?
183 end
183 end
184 end
184 end
185
185
186 private
186 private
187 def initialize_defaults(method_name)
187 def initialize_defaults(method_name)
188 super
188 super
189 set_language_if_valid Setting.default_language
189 set_language_if_valid Setting.default_language
190 from Setting.mail_from
190 from Setting.mail_from
191
191
192 # URL options
192 # URL options
193 h = Setting.host_name
193 h = Setting.host_name
194 h = h.to_s.gsub(%r{\/.*$}, '') unless ActionController::AbstractRequest.relative_url_root.blank?
194 h = h.to_s.gsub(%r{\/.*$}, '') unless Redmine::Utils.relative_url_root.blank?
195 default_url_options[:host] = h
195 default_url_options[:host] = h
196 default_url_options[:protocol] = Setting.protocol
196 default_url_options[:protocol] = Setting.protocol
197
197
198 # Common headers
198 # Common headers
199 headers 'X-Mailer' => 'Redmine',
199 headers 'X-Mailer' => 'Redmine',
200 'X-Redmine-Host' => Setting.host_name,
200 'X-Redmine-Host' => Setting.host_name,
201 'X-Redmine-Site' => Setting.app_title
201 'X-Redmine-Site' => Setting.app_title
202 end
202 end
203
203
204 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
204 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
205 def redmine_headers(h)
205 def redmine_headers(h)
206 h.each { |k,v| headers["X-Redmine-#{k}"] = v }
206 h.each { |k,v| headers["X-Redmine-#{k}"] = v }
207 end
207 end
208
208
209 # Overrides the create_mail method
209 # Overrides the create_mail method
210 def create_mail
210 def create_mail
211 # Removes the current user from the recipients and cc
211 # Removes the current user from the recipients and cc
212 # if he doesn't want to receive notifications about what he does
212 # if he doesn't want to receive notifications about what he does
213 @author ||= User.current
213 @author ||= User.current
214 if @author.pref[:no_self_notified]
214 if @author.pref[:no_self_notified]
215 recipients.delete(@author.mail) if recipients
215 recipients.delete(@author.mail) if recipients
216 cc.delete(@author.mail) if cc
216 cc.delete(@author.mail) if cc
217 end
217 end
218 # Blind carbon copy recipients
218 # Blind carbon copy recipients
219 if Setting.bcc_recipients?
219 if Setting.bcc_recipients?
220 bcc([recipients, cc].flatten.compact.uniq)
220 bcc([recipients, cc].flatten.compact.uniq)
221 recipients []
221 recipients []
222 cc []
222 cc []
223 end
223 end
224 super
224 super
225 end
225 end
226
226
227 # Renders a message with the corresponding layout
227 # Renders a message with the corresponding layout
228 def render_message(method_name, body)
228 def render_message(method_name, body)
229 layout = method_name.match(%r{text\.html\.(rhtml|rxml)}) ? 'layout.text.html.rhtml' : 'layout.text.plain.rhtml'
229 layout = method_name.to_s.match(%r{text\.html\.(rhtml|rxml)}) ? 'layout.text.html.rhtml' : 'layout.text.plain.rhtml'
230 body[:content_for_layout] = render(:file => method_name, :body => body)
230 body[:content_for_layout] = render(:file => method_name, :body => body)
231 ActionView::Base.new(template_root, body, self).render(:file => "mailer/#{layout}", :use_full_path => true)
231 ActionView::Base.new(template_root, body, self).render(:file => "mailer/#{layout}", :use_full_path => true)
232 end
232 end
233
233
234 # for the case of plain text only
234 # for the case of plain text only
235 def body(*params)
235 def body(*params)
236 value = super(*params)
236 value = super(*params)
237 if Setting.plain_text_mail?
237 if Setting.plain_text_mail?
238 templates = Dir.glob("#{template_path}/#{@template}.text.plain.{rhtml,erb}")
238 templates = Dir.glob("#{template_path}/#{@template}.text.plain.{rhtml,erb}")
239 unless String === @body or templates.empty?
239 unless String === @body or templates.empty?
240 template = File.basename(templates.first)
240 template = File.basename(templates.first)
241 @body[:content_for_layout] = render(:file => template, :body => @body)
241 @body[:content_for_layout] = render(:file => template, :body => @body)
242 @body = ActionView::Base.new(template_root, @body, self).render(:file => "mailer/layout.text.plain.rhtml", :use_full_path => true)
242 @body = ActionView::Base.new(template_root, @body, self).render(:file => "mailer/layout.text.plain.rhtml", :use_full_path => true)
243 return @body
243 return @body
244 end
244 end
245 end
245 end
246 return value
246 return value
247 end
247 end
248
248
249 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
249 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
250 def self.controller_path
250 def self.controller_path
251 ''
251 ''
252 end unless respond_to?('controller_path')
252 end unless respond_to?('controller_path')
253 end
253 end
@@ -1,47 +1,46
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module WikiFormatting
19 module WikiFormatting
20 module Textile
20 module Textile
21 module Helper
21 module Helper
22 def wikitoolbar_for(field_id)
22 def wikitoolbar_for(field_id)
23 # Is there a simple way to link to a public resource?
23 # Is there a simple way to link to a public resource?
24 prefix = (ActionController::Base.respond_to?(:relative_url_root) ? ActionController::Base.relative_url_root : ActionController::AbstractRequest.relative_url_root)
24 url = "#{Redmine::Utils.relative_url_root}/help/wiki_syntax.html"
25 url = "#{prefix}/help/wiki_syntax.html"
26
25
27 help_link = l(:setting_text_formatting) + ': ' +
26 help_link = l(:setting_text_formatting) + ': ' +
28 link_to(l(:label_help), url,
27 link_to(l(:label_help), url,
29 :onclick => "window.open(\"#{ url }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
28 :onclick => "window.open(\"#{ url }\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")
30
29
31 javascript_include_tag('jstoolbar/jstoolbar') +
30 javascript_include_tag('jstoolbar/jstoolbar') +
32 javascript_include_tag('jstoolbar/textile') +
31 javascript_include_tag('jstoolbar/textile') +
33 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
32 javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language}") +
34 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
33 javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
35 end
34 end
36
35
37 def initial_page_content(page)
36 def initial_page_content(page)
38 "h1. #{@page.pretty_title}"
37 "h1. #{@page.pretty_title}"
39 end
38 end
40
39
41 def heads_for_wiki_formatter
40 def heads_for_wiki_formatter
42 stylesheet_link_tag 'jstoolbar'
41 stylesheet_link_tag 'jstoolbar'
43 end
42 end
44 end
43 end
45 end
44 end
46 end
45 end
47 end
46 end
@@ -1,186 +1,186
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19
19
20 class MailerTest < Test::Unit::TestCase
20 class MailerTest < Test::Unit::TestCase
21 fixtures :projects, :issues, :users, :members, :documents, :attachments, :news, :tokens, :journals, :journal_details, :changesets, :trackers, :issue_statuses, :enumerations, :messages, :boards, :repositories
21 fixtures :projects, :issues, :users, :members, :documents, :attachments, :news, :tokens, :journals, :journal_details, :changesets, :trackers, :issue_statuses, :enumerations, :messages, :boards, :repositories
22
22
23 def test_generated_links_in_emails
23 def test_generated_links_in_emails
24 ActionMailer::Base.deliveries.clear
24 ActionMailer::Base.deliveries.clear
25 Setting.host_name = 'mydomain.foo'
25 Setting.host_name = 'mydomain.foo'
26 Setting.protocol = 'https'
26 Setting.protocol = 'https'
27
27
28 journal = Journal.find(2)
28 journal = Journal.find(2)
29 assert Mailer.deliver_issue_edit(journal)
29 assert Mailer.deliver_issue_edit(journal)
30
30
31 mail = ActionMailer::Base.deliveries.last
31 mail = ActionMailer::Base.deliveries.last
32 assert_kind_of TMail::Mail, mail
32 assert_kind_of TMail::Mail, mail
33 # link to the main ticket
33 # link to the main ticket
34 assert mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>')
34 assert mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>')
35
35
36 # link to a referenced ticket
36 # link to a referenced ticket
37 assert mail.body.include?('<a href="https://mydomain.foo/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
37 assert mail.body.include?('<a href="https://mydomain.foo/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
38 # link to a changeset
38 # link to a changeset
39 assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
39 assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
40 end
40 end
41
41
42 def test_generated_links_with_prefix
42 def test_generated_links_with_prefix
43 relative_url_root = ActionController::AbstractRequest.relative_url_root
43 relative_url_root = Redmine::Utils.relative_url_root
44 ActionMailer::Base.deliveries.clear
44 ActionMailer::Base.deliveries.clear
45 Setting.host_name = 'mydomain.foo/rdm'
45 Setting.host_name = 'mydomain.foo/rdm'
46 Setting.protocol = 'http'
46 Setting.protocol = 'http'
47 ActionController::AbstractRequest.relative_url_root = '/rdm'
47 Redmine::Utils.relative_url_root = '/rdm'
48
48
49 journal = Journal.find(2)
49 journal = Journal.find(2)
50 assert Mailer.deliver_issue_edit(journal)
50 assert Mailer.deliver_issue_edit(journal)
51
51
52 mail = ActionMailer::Base.deliveries.last
52 mail = ActionMailer::Base.deliveries.last
53 assert_kind_of TMail::Mail, mail
53 assert_kind_of TMail::Mail, mail
54 # link to the main ticket
54 # link to the main ticket
55 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/1">Bug #1: Can\'t print recipes</a>')
55 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/1">Bug #1: Can\'t print recipes</a>')
56
56
57 # link to a referenced ticket
57 # link to a referenced ticket
58 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
58 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
59 # link to a changeset
59 # link to a changeset
60 assert mail.body.include?('<a href="http://mydomain.foo/rdm/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
60 assert mail.body.include?('<a href="http://mydomain.foo/rdm/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
61 ensure
61 ensure
62 # restore it
62 # restore it
63 ActionController::AbstractRequest.relative_url_root = relative_url_root
63 Redmine::Utils.relative_url_root = relative_url_root
64 end
64 end
65
65
66 def test_generated_links_with_prefix_and_no_relative_url_root
66 def test_generated_links_with_prefix_and_no_relative_url_root
67 relative_url_root = ActionController::AbstractRequest.relative_url_root
67 relative_url_root = Redmine::Utils.relative_url_root
68 ActionMailer::Base.deliveries.clear
68 ActionMailer::Base.deliveries.clear
69 Setting.host_name = 'mydomain.foo/rdm'
69 Setting.host_name = 'mydomain.foo/rdm'
70 Setting.protocol = 'http'
70 Setting.protocol = 'http'
71 ActionController::AbstractRequest.relative_url_root = nil
71 Redmine::Utils.relative_url_root = nil
72
72
73 journal = Journal.find(2)
73 journal = Journal.find(2)
74 assert Mailer.deliver_issue_edit(journal)
74 assert Mailer.deliver_issue_edit(journal)
75
75
76 mail = ActionMailer::Base.deliveries.last
76 mail = ActionMailer::Base.deliveries.last
77 assert_kind_of TMail::Mail, mail
77 assert_kind_of TMail::Mail, mail
78 # link to the main ticket
78 # link to the main ticket
79 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/1">Bug #1: Can\'t print recipes</a>')
79 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/1">Bug #1: Can\'t print recipes</a>')
80
80
81 # link to a referenced ticket
81 # link to a referenced ticket
82 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
82 assert mail.body.include?('<a href="http://mydomain.foo/rdm/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
83 # link to a changeset
83 # link to a changeset
84 assert mail.body.include?('<a href="http://mydomain.foo/rdm/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
84 assert mail.body.include?('<a href="http://mydomain.foo/rdm/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 &amp; #3">r2</a>')
85 ensure
85 ensure
86 # restore it
86 # restore it
87 ActionController::AbstractRequest.relative_url_root = relative_url_root
87 Redmine::Utils.relative_url_root = relative_url_root
88 end
88 end
89
89
90 def test_plain_text_mail
90 def test_plain_text_mail
91 Setting.plain_text_mail = 1
91 Setting.plain_text_mail = 1
92 journal = Journal.find(2)
92 journal = Journal.find(2)
93 Mailer.deliver_issue_edit(journal)
93 Mailer.deliver_issue_edit(journal)
94 mail = ActionMailer::Base.deliveries.last
94 mail = ActionMailer::Base.deliveries.last
95 assert !mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>')
95 assert !mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>')
96 end
96 end
97
97
98
98
99
99
100 # test mailer methods for each language
100 # test mailer methods for each language
101 def test_issue_add
101 def test_issue_add
102 issue = Issue.find(1)
102 issue = Issue.find(1)
103 GLoc.valid_languages.each do |lang|
103 GLoc.valid_languages.each do |lang|
104 Setting.default_language = lang.to_s
104 Setting.default_language = lang.to_s
105 assert Mailer.deliver_issue_add(issue)
105 assert Mailer.deliver_issue_add(issue)
106 end
106 end
107 end
107 end
108
108
109 def test_issue_edit
109 def test_issue_edit
110 journal = Journal.find(1)
110 journal = Journal.find(1)
111 GLoc.valid_languages.each do |lang|
111 GLoc.valid_languages.each do |lang|
112 Setting.default_language = lang.to_s
112 Setting.default_language = lang.to_s
113 assert Mailer.deliver_issue_edit(journal)
113 assert Mailer.deliver_issue_edit(journal)
114 end
114 end
115 end
115 end
116
116
117 def test_document_added
117 def test_document_added
118 document = Document.find(1)
118 document = Document.find(1)
119 GLoc.valid_languages.each do |lang|
119 GLoc.valid_languages.each do |lang|
120 Setting.default_language = lang.to_s
120 Setting.default_language = lang.to_s
121 assert Mailer.deliver_document_added(document)
121 assert Mailer.deliver_document_added(document)
122 end
122 end
123 end
123 end
124
124
125 def test_attachments_added
125 def test_attachments_added
126 attachements = [ Attachment.find_by_container_type('Document') ]
126 attachements = [ Attachment.find_by_container_type('Document') ]
127 GLoc.valid_languages.each do |lang|
127 GLoc.valid_languages.each do |lang|
128 Setting.default_language = lang.to_s
128 Setting.default_language = lang.to_s
129 assert Mailer.deliver_attachments_added(attachements)
129 assert Mailer.deliver_attachments_added(attachements)
130 end
130 end
131 end
131 end
132
132
133 def test_news_added
133 def test_news_added
134 news = News.find(:first)
134 news = News.find(:first)
135 GLoc.valid_languages.each do |lang|
135 GLoc.valid_languages.each do |lang|
136 Setting.default_language = lang.to_s
136 Setting.default_language = lang.to_s
137 assert Mailer.deliver_news_added(news)
137 assert Mailer.deliver_news_added(news)
138 end
138 end
139 end
139 end
140
140
141 def test_message_posted
141 def test_message_posted
142 message = Message.find(:first)
142 message = Message.find(:first)
143 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
143 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
144 recipients = recipients.compact.uniq
144 recipients = recipients.compact.uniq
145 GLoc.valid_languages.each do |lang|
145 GLoc.valid_languages.each do |lang|
146 Setting.default_language = lang.to_s
146 Setting.default_language = lang.to_s
147 assert Mailer.deliver_message_posted(message, recipients)
147 assert Mailer.deliver_message_posted(message, recipients)
148 end
148 end
149 end
149 end
150
150
151 def test_account_information
151 def test_account_information
152 user = User.find(:first)
152 user = User.find(:first)
153 GLoc.valid_languages.each do |lang|
153 GLoc.valid_languages.each do |lang|
154 user.update_attribute :language, lang.to_s
154 user.update_attribute :language, lang.to_s
155 user.reload
155 user.reload
156 assert Mailer.deliver_account_information(user, 'pAsswORd')
156 assert Mailer.deliver_account_information(user, 'pAsswORd')
157 end
157 end
158 end
158 end
159
159
160 def test_lost_password
160 def test_lost_password
161 token = Token.find(2)
161 token = Token.find(2)
162 GLoc.valid_languages.each do |lang|
162 GLoc.valid_languages.each do |lang|
163 token.user.update_attribute :language, lang.to_s
163 token.user.update_attribute :language, lang.to_s
164 token.reload
164 token.reload
165 assert Mailer.deliver_lost_password(token)
165 assert Mailer.deliver_lost_password(token)
166 end
166 end
167 end
167 end
168
168
169 def test_register
169 def test_register
170 token = Token.find(1)
170 token = Token.find(1)
171 GLoc.valid_languages.each do |lang|
171 GLoc.valid_languages.each do |lang|
172 token.user.update_attribute :language, lang.to_s
172 token.user.update_attribute :language, lang.to_s
173 token.reload
173 token.reload
174 assert Mailer.deliver_register(token)
174 assert Mailer.deliver_register(token)
175 end
175 end
176 end
176 end
177
177
178 def test_reminders
178 def test_reminders
179 ActionMailer::Base.deliveries.clear
179 ActionMailer::Base.deliveries.clear
180 Mailer.reminders(:days => 42)
180 Mailer.reminders(:days => 42)
181 assert_equal 1, ActionMailer::Base.deliveries.size
181 assert_equal 1, ActionMailer::Base.deliveries.size
182 mail = ActionMailer::Base.deliveries.last
182 mail = ActionMailer::Base.deliveries.last
183 assert mail.bcc.include?('dlopper@somenet.foo')
183 assert mail.bcc.include?('dlopper@somenet.foo')
184 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
184 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
185 end
185 end
186 end
186 end
General Comments 0
You need to be logged in to leave comments. Login now