Revision 1298:4f746d8966dd .svn/pristine/09

View differences:

.svn/pristine/09/0950951344735156104a9fd2df5df66fc9bd2194.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  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 Views
20
    module Builders
21
      def self.for(format, &block)
22
        builder = case format
23
          when 'xml',  :xml;  Builders::Xml.new
24
          when 'json', :json; Builders::Json.new
25
          else; raise "No builder for format #{format}"
26
        end
27
        if block
28
          block.call(builder)
29
        else
30
          builder
31
        end
32
      end
33
    end
34
  end
35
end
.svn/pristine/09/095b395fcfe029ccbb2acac47d6cc8ef84b80f97.svn-base
1
syntax: glob
2

  
3
.project
4
.loadpath
5
config/additional_environment.rb
6
config/configuration.yml
7
config/database.yml
8
config/email.yml
9
config/initializers/session_store.rb
10
coverage
11
db/*.db
12
db/*.sqlite3
13
db/schema.rb
14
files/*
15
lib/redmine/scm/adapters/mercurial/redminehelper.pyc
16
lib/redmine/scm/adapters/mercurial/redminehelper.pyo
17
log/*.log*
18
log/mongrel_debug
19
public/dispatch.*
20
public/plugin_assets
21
tmp/*
22
tmp/cache/*
23
tmp/sessions/*
24
tmp/sockets/*
25
tmp/test/*
26
vendor/rails
27
*.rbc
28

  
29
.svn/
30
.git/
31

  
32
.bundle
33
Gemfile.lock
34
Gemfile.local
35

  
.svn/pristine/09/09843d45a0a3ac966e4fda0bad80ec81990f71bb.svn-base
1
Net::LDAP is copyrighted free software by Francis Cianfrocca
2
<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either
3
the terms of the GPL (see the file COPYING), or the conditions below:
4

  
5
1. You may make and give away verbatim copies of the source form of the
6
   software without restriction, provided that you duplicate all of the
7
   original copyright notices and associated disclaimers.
8

  
9
2. You may modify your copy of the software in any way, provided that you do
10
   at least ONE of the following:
11

  
12
   a) place your modifications in the Public Domain or otherwise make them
13
      Freely Available, such as by posting said modifications to Usenet or
14
      an equivalent medium, or by allowing the author to include your
15
      modifications in the software.
16

  
17
   b) use the modified software only within your corporation or
18
      organization.
19

  
20
   c) rename any non-standard executables so the names do not conflict with
21
      standard executables, which must also be provided.
22

  
23
   d) make other distribution arrangements with the author.
24

  
25
3. You may distribute the software in object code or executable form,
26
   provided that you do at least ONE of the following:
27

  
28
   a) distribute the executables and library files of the software, together
29
      with instructions (in the manual page or equivalent) on where to get
30
      the original distribution.
31

  
32
   b) accompany the distribution with the machine-readable source of the
33
      software.
34

  
35
   c) give non-standard executables non-standard names, with instructions on
36
      where to get the original software distribution.
37

  
38
   d) make other distribution arrangements with the author.
39

  
40
4. You may modify and include the part of the software into any other
41
   software (possibly commercial).  But some files in the distribution are
42
   not written by the author, so that they are not under this terms.
43

  
44
   They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
   files under the ./missing directory.  See each file for the copying
46
   condition.
47

  
48
5. The scripts and library files supplied as input to or produced as output
49
   from the software do not automatically fall under the copyright of the
50
   software, but belong to whomever generated them, and may be sold
51
   commercially, and may be aggregated with this software.
52

  
53
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
54
   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
55
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.svn/pristine/09/09d005add00d07aeb449a6c04ad00db8e1f72fbd.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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
require File.expand_path('../../../test_helper', __FILE__)
19

  
20
class RoutingMyTest < ActionController::IntegrationTest
21
  def test_my
22
    ["get", "post"].each do |method|
23
      assert_routing(
24
          { :method => method, :path => "/my/account" },
25
          { :controller => 'my', :action => 'account' }
26
        )
27
    end
28
    ["get", "post"].each do |method|
29
      assert_routing(
30
          { :method => method, :path => "/my/account/destroy" },
31
          { :controller => 'my', :action => 'destroy' }
32
        )
33
    end
34
    assert_routing(
35
        { :method => 'get', :path => "/my/page" },
36
        { :controller => 'my', :action => 'page' }
37
      )
38
    assert_routing(
39
        { :method => 'get', :path => "/my" },
40
        { :controller => 'my', :action => 'index' }
41
      )
42
    assert_routing(
43
        { :method => 'post', :path => "/my/reset_rss_key" },
44
        { :controller => 'my', :action => 'reset_rss_key' }
45
      )
46
    assert_routing(
47
        { :method => 'post', :path => "/my/reset_api_key" },
48
        { :controller => 'my', :action => 'reset_api_key' }
49
      )
50
    ["get", "post"].each do |method|
51
      assert_routing(
52
          { :method => method, :path => "/my/password" },
53
          { :controller => 'my', :action => 'password' }
54
        )
55
    end
56
    assert_routing(
57
        { :method => 'get', :path => "/my/page_layout" },
58
        { :controller => 'my', :action => 'page_layout' }
59
      )
60
    assert_routing(
61
        { :method => 'post', :path => "/my/add_block" },
62
        { :controller => 'my', :action => 'add_block' }
63
      )
64
    assert_routing(
65
        { :method => 'post', :path => "/my/remove_block" },
66
        { :controller => 'my', :action => 'remove_block' }
67
      )
68
    assert_routing(
69
        { :method => 'post', :path => "/my/order_blocks" },
70
        { :controller => 'my', :action => 'order_blocks' }
71
      )
72
  end
73
end
.svn/pristine/09/09e163f7a5ba48f41a7d0433361b8d9b46760493.svn-base
1
<%= error_messages_for 'query' %>
2

  
3
<div class="box">
4
<div class="tabular">
5
<p><label for="query_name"><%=l(:field_name)%></label>
6
<%= text_field 'query', 'name', :size => 80 %></p>
7

  
8
<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %>
9
<p><label for="query_is_public"><%=l(:field_is_public)%></label>
10
<%= check_box 'query', 'is_public',
11
      :onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
12
<% end %>
13

  
14
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label>
15
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?,
16
      :disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p>
17

  
18
<p><label for="query_default_columns"><%=l(:label_default_columns)%></label>
19
<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
20
      :onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
21

  
22
<p><label for="query_group_by"><%= l(:field_group_by) %></label>
23
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
24

  
25
<p><label><%= l(:button_show) %></label>
26
<%= available_block_columns_tags(@query) %></p>
27
</div>
28

  
29
<fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend>
30
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
31
</fieldset>
32

  
33
<fieldset><legend><%= l(:label_sort) %></legend>
34
<% 3.times do |i| %>
35
<%= i+1 %>: 
36
<%= label_tag "query_sort_criteria_attribute_" + i.to_s,
37
              l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %>
38
<%= select_tag("query[sort_criteria][#{i}][]",
39
               options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
40
               :id => "query_sort_criteria_attribute_" + i.to_s)%>
41
<%= label_tag "query_sort_criteria_direction_" + i.to_s,
42
              l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %>
43
<%= select_tag("query[sort_criteria][#{i}][]",
44
                options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)),
45
                :id => "query_sort_criteria_direction_" + i.to_s) %>
46
<br />
47
<% end %>
48
</fieldset>
49

  
50
<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
51
<legend><%= l(:field_column_names) %></legend>
52
<%= render_query_columns_selection(query) %>
53
<% end %>
54

  
55
</div>
.svn/pristine/09/09eb85d785f24ac92c1ca5060b63ab8922db4494.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  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
class Mailer < ActionMailer::Base
19
  layout 'mailer'
20
  helper :application
21
  helper :issues
22
  helper :custom_fields
23

  
24
  include Redmine::I18n
25

  
26
  def self.default_url_options
27
    { :host => Setting.host_name, :protocol => Setting.protocol }
28
  end
29

  
30
  # Builds a Mail::Message object used to email recipients of the added issue.
31
  #
32
  # Example:
33
  #   issue_add(issue) => Mail::Message object
34
  #   Mailer.issue_add(issue).deliver => sends an email to issue recipients
35
  def issue_add(issue)
36
    redmine_headers 'Project' => issue.project.identifier,
37
                    'Issue-Id' => issue.id,
38
                    'Issue-Author' => issue.author.login
39
    redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
40
    message_id issue
41
    @author = issue.author
42
    @issue = issue
43
    @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
44
    recipients = issue.recipients
45
    cc = issue.watcher_recipients - recipients
46
    mail :to => recipients,
47
      :cc => cc,
48
      :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
49
  end
50

  
51
  # Builds a Mail::Message object used to email recipients of the edited issue.
52
  #
53
  # Example:
54
  #   issue_edit(journal) => Mail::Message object
55
  #   Mailer.issue_edit(journal).deliver => sends an email to issue recipients
56
  def issue_edit(journal)
57
    issue = journal.journalized.reload
58
    redmine_headers 'Project' => issue.project.identifier,
59
                    'Issue-Id' => issue.id,
60
                    'Issue-Author' => issue.author.login
61
    redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
62
    message_id journal
63
    references issue
64
    @author = journal.user
65
    recipients = journal.recipients
66
    # Watchers in cc
67
    cc = journal.watcher_recipients - recipients
68
    s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
69
    s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
70
    s << issue.subject
71
    @issue = issue
72
    @journal = journal
73
    @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
74
    mail :to => recipients,
75
      :cc => cc,
76
      :subject => s
77
  end
78

  
79
  def reminder(user, issues, days)
80
    set_language_if_valid user.language
81
    @issues = issues
82
    @days = days
83
    @issues_url = url_for(:controller => 'issues', :action => 'index',
84
                                :set_filter => 1, :assigned_to_id => user.id,
85
                                :sort => 'due_date:asc')
86
    mail :to => user.mail,
87
      :subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
88
  end
89

  
90
  # Builds a Mail::Message object used to email users belonging to the added document's project.
91
  #
92
  # Example:
93
  #   document_added(document) => Mail::Message object
94
  #   Mailer.document_added(document).deliver => sends an email to the document's project recipients
95
  def document_added(document)
96
    redmine_headers 'Project' => document.project.identifier
97
    @author = User.current
98
    @document = document
99
    @document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
100
    mail :to => document.recipients,
101
      :subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
102
  end
103

  
104
  # Builds a Mail::Message object used to email recipients of a project when an attachements are added.
105
  #
106
  # Example:
107
  #   attachments_added(attachments) => Mail::Message object
108
  #   Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
109
  def attachments_added(attachments)
110
    container = attachments.first.container
111
    added_to = ''
112
    added_to_url = ''
113
    @author = attachments.first.author
114
    case container.class.name
115
    when 'Project'
116
      added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
117
      added_to = "#{l(:label_project)}: #{container}"
118
      recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect  {|u| u.mail}
119
    when 'Version'
120
      added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
121
      added_to = "#{l(:label_version)}: #{container.name}"
122
      recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect  {|u| u.mail}
123
    when 'Document'
124
      added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
125
      added_to = "#{l(:label_document)}: #{container.title}"
126
      recipients = container.recipients
127
    end
128
    redmine_headers 'Project' => container.project.identifier
129
    @attachments = attachments
130
    @added_to = added_to
131
    @added_to_url = added_to_url
132
    mail :to => recipients,
133
      :subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
134
  end
135

  
136
  # Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
137
  #
138
  # Example:
139
  #   news_added(news) => Mail::Message object
140
  #   Mailer.news_added(news).deliver => sends an email to the news' project recipients
141
  def news_added(news)
142
    redmine_headers 'Project' => news.project.identifier
143
    @author = news.author
144
    message_id news
145
    @news = news
146
    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
147
    mail :to => news.recipients,
148
      :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
149
  end
150

  
151
  # Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
152
  #
153
  # Example:
154
  #   news_comment_added(comment) => Mail::Message object
155
  #   Mailer.news_comment_added(comment) => sends an email to the news' project recipients
156
  def news_comment_added(comment)
157
    news = comment.commented
158
    redmine_headers 'Project' => news.project.identifier
159
    @author = comment.author
160
    message_id comment
161
    @news = news
162
    @comment = comment
163
    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
164
    mail :to => news.recipients,
165
     :cc => news.watcher_recipients,
166
     :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
167
  end
168

  
169
  # Builds a Mail::Message object used to email the recipients of the specified message that was posted.
170
  #
171
  # Example:
172
  #   message_posted(message) => Mail::Message object
173
  #   Mailer.message_posted(message).deliver => sends an email to the recipients
174
  def message_posted(message)
175
    redmine_headers 'Project' => message.project.identifier,
176
                    'Topic-Id' => (message.parent_id || message.id)
177
    @author = message.author
178
    message_id message
179
    references message.parent unless message.parent.nil?
180
    recipients = message.recipients
181
    cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
182
    @message = message
183
    @message_url = url_for(message.event_url)
184
    mail :to => recipients,
185
      :cc => cc,
186
      :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
187
  end
188

  
189
  # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
190
  #
191
  # Example:
192
  #   wiki_content_added(wiki_content) => Mail::Message object
193
  #   Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
194
  def wiki_content_added(wiki_content)
195
    redmine_headers 'Project' => wiki_content.project.identifier,
196
                    'Wiki-Page-Id' => wiki_content.page.id
197
    @author = wiki_content.author
198
    message_id wiki_content
199
    recipients = wiki_content.recipients
200
    cc = wiki_content.page.wiki.watcher_recipients - recipients
201
    @wiki_content = wiki_content
202
    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
203
                                      :project_id => wiki_content.project,
204
                                      :id => wiki_content.page.title)
205
    mail :to => recipients,
206
      :cc => cc,
207
      :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
208
  end
209

  
210
  # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
211
  #
212
  # Example:
213
  #   wiki_content_updated(wiki_content) => Mail::Message object
214
  #   Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
215
  def wiki_content_updated(wiki_content)
216
    redmine_headers 'Project' => wiki_content.project.identifier,
217
                    'Wiki-Page-Id' => wiki_content.page.id
218
    @author = wiki_content.author
219
    message_id wiki_content
220
    recipients = wiki_content.recipients
221
    cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
222
    @wiki_content = wiki_content
223
    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
224
                                      :project_id => wiki_content.project,
225
                                      :id => wiki_content.page.title)
226
    @wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
227
                                   :project_id => wiki_content.project, :id => wiki_content.page.title,
228
                                   :version => wiki_content.version)
229
    mail :to => recipients,
230
      :cc => cc,
231
      :subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
232
  end
233

  
234
  # Builds a Mail::Message object used to email the specified user their account information.
235
  #
236
  # Example:
237
  #   account_information(user, password) => Mail::Message object
238
  #   Mailer.account_information(user, password).deliver => sends account information to the user
239
  def account_information(user, password)
240
    set_language_if_valid user.language
241
    @user = user
242
    @password = password
243
    @login_url = url_for(:controller => 'account', :action => 'login')
244
    mail :to => user.mail,
245
      :subject => l(:mail_subject_register, Setting.app_title)
246
  end
247

  
248
  # Builds a Mail::Message object used to email all active administrators of an account activation request.
249
  #
250
  # Example:
251
  #   account_activation_request(user) => Mail::Message object
252
  #   Mailer.account_activation_request(user).deliver => sends an email to all active administrators
253
  def account_activation_request(user)
254
    # Send the email to all active administrators
255
    recipients = User.active.where(:admin => true).all.collect { |u| u.mail }.compact
256
    @user = user
257
    @url = url_for(:controller => 'users', :action => 'index',
258
                         :status => User::STATUS_REGISTERED,
259
                         :sort_key => 'created_on', :sort_order => 'desc')
260
    mail :to => recipients,
261
      :subject => l(:mail_subject_account_activation_request, Setting.app_title)
262
  end
263

  
264
  # Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
265
  #
266
  # Example:
267
  #   account_activated(user) => Mail::Message object
268
  #   Mailer.account_activated(user).deliver => sends an email to the registered user
269
  def account_activated(user)
270
    set_language_if_valid user.language
271
    @user = user
272
    @login_url = url_for(:controller => 'account', :action => 'login')
273
    mail :to => user.mail,
274
      :subject => l(:mail_subject_register, Setting.app_title)
275
  end
276

  
277
  def lost_password(token)
278
    set_language_if_valid(token.user.language)
279
    @token = token
280
    @url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
281
    mail :to => token.user.mail,
282
      :subject => l(:mail_subject_lost_password, Setting.app_title)
283
  end
284

  
285
  def register(token)
286
    set_language_if_valid(token.user.language)
287
    @token = token
288
    @url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
289
    mail :to => token.user.mail,
290
      :subject => l(:mail_subject_register, Setting.app_title)
291
  end
292

  
293
  def test_email(user)
294
    set_language_if_valid(user.language)
295
    @url = url_for(:controller => 'welcome')
296
    mail :to => user.mail,
297
      :subject => 'Redmine test'
298
  end
299

  
300
  # Overrides default deliver! method to prevent from sending an email
301
  # with no recipient, cc or bcc
302
  def deliver!(mail = @mail)
303
    set_language_if_valid @initial_language
304
    return false if (recipients.nil? || recipients.empty?) &&
305
                    (cc.nil? || cc.empty?) &&
306
                    (bcc.nil? || bcc.empty?)
307

  
308

  
309
    # Log errors when raise_delivery_errors is set to false, Rails does not
310
    raise_errors = self.class.raise_delivery_errors
311
    self.class.raise_delivery_errors = true
312
    begin
313
      return super(mail)
314
    rescue Exception => e
315
      if raise_errors
316
        raise e
317
      elsif mylogger
318
        mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
319
      end
320
    ensure
321
      self.class.raise_delivery_errors = raise_errors
322
    end
323
  end
324

  
325
  # Sends reminders to issue assignees
326
  # Available options:
327
  # * :days     => how many days in the future to remind about (defaults to 7)
328
  # * :tracker  => id of tracker for filtering issues (defaults to all trackers)
329
  # * :project  => id or identifier of project to process (defaults to all projects)
330
  # * :users    => array of user/group ids who should be reminded
331
  def self.reminders(options={})
332
    days = options[:days] || 7
333
    project = options[:project] ? Project.find(options[:project]) : nil
334
    tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
335
    user_ids = options[:users]
336

  
337
    scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
338
      " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
339
      " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
340
    )
341
    scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
342
    scope = scope.where(:project_id => project.id) if project
343
    scope = scope.where(:tracker_id => tracker.id) if tracker
344

  
345
    issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).all.group_by(&:assigned_to)
346
    issues_by_assignee.keys.each do |assignee|
347
      if assignee.is_a?(Group)
348
        assignee.users.each do |user|
349
          issues_by_assignee[user] ||= []
350
          issues_by_assignee[user] += issues_by_assignee[assignee]
351
        end
352
      end
353
    end
354

  
355
    issues_by_assignee.each do |assignee, issues|
356
      reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
357
    end
358
  end
359

  
360
  # Activates/desactivates email deliveries during +block+
361
  def self.with_deliveries(enabled = true, &block)
362
    was_enabled = ActionMailer::Base.perform_deliveries
363
    ActionMailer::Base.perform_deliveries = !!enabled
364
    yield
365
  ensure
366
    ActionMailer::Base.perform_deliveries = was_enabled
367
  end
368

  
369
  # Sends emails synchronously in the given block
370
  def self.with_synched_deliveries(&block)
371
    saved_method = ActionMailer::Base.delivery_method
372
    if m = saved_method.to_s.match(%r{^async_(.+)$})
373
      synched_method = m[1]
374
      ActionMailer::Base.delivery_method = synched_method.to_sym
375
      ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
376
    end
377
    yield
378
  ensure
379
    ActionMailer::Base.delivery_method = saved_method
380
  end
381

  
382
  def mail(headers={})
383
    headers.merge! 'X-Mailer' => 'Redmine',
384
            'X-Redmine-Host' => Setting.host_name,
385
            'X-Redmine-Site' => Setting.app_title,
386
            'X-Auto-Response-Suppress' => 'OOF',
387
            'Auto-Submitted' => 'auto-generated',
388
            'From' => Setting.mail_from,
389
            'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
390

  
391
    # Removes the author from the recipients and cc
392
    # if he doesn't want to receive notifications about what he does
393
    if @author && @author.logged? && @author.pref[:no_self_notified]
394
      headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
395
      headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
396
    end
397

  
398
    if @author && @author.logged?
399
      redmine_headers 'Sender' => @author.login
400
    end
401

  
402
    # Blind carbon copy recipients
403
    if Setting.bcc_recipients?
404
      headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
405
      headers[:to] = nil
406
      headers[:cc] = nil
407
    end
408

  
409
    if @message_id_object
410
      headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
411
    end
412
    if @references_objects
413
      headers[:references] = @references_objects.collect {|o| "<#{self.class.message_id_for(o)}>"}.join(' ')
414
    end
415

  
416
    super headers do |format|
417
      format.text
418
      format.html unless Setting.plain_text_mail?
419
    end
420

  
421
    set_language_if_valid @initial_language
422
  end
423

  
424
  def initialize(*args)
425
    @initial_language = current_language
426
    set_language_if_valid Setting.default_language
427
    super
428
  end
429
  
430
  def self.deliver_mail(mail)
431
    return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
432
    super
433
  end
434

  
435
  def self.method_missing(method, *args, &block)
436
    if m = method.to_s.match(%r{^deliver_(.+)$})
437
      ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
438
      send(m[1], *args).deliver
439
    else
440
      super
441
    end
442
  end
443

  
444
  private
445

  
446
  # Appends a Redmine header field (name is prepended with 'X-Redmine-')
447
  def redmine_headers(h)
448
    h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
449
  end
450

  
451
  # Returns a predictable Message-Id for the given object
452
  def self.message_id_for(object)
453
    # id + timestamp should reduce the odds of a collision
454
    # as far as we don't send multiple emails for the same object
455
    timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
456
    hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
457
    host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
458
    host = "#{::Socket.gethostname}.redmine" if host.empty?
459
    "#{hash}@#{host}"
460
  end
461

  
462
  def message_id(object)
463
    @message_id_object = object
464
  end
465

  
466
  def references(object)
467
    @references_objects ||= []
468
    @references_objects << object
469
  end
470

  
471
  def mylogger
472
    Rails.logger
473
  end
474
end
.svn/pristine/09/09ee2f48a5aafa2ec6da3a021e076cc86af61f01.svn-base
1
<h2><%= l(:label_board_new) %></h2>
2

  
3
<% labelled_tabular_form_for :board, @board, :url => {:action => 'new'} do |f| %>
4
  <%= render :partial => 'form', :locals => {:f => f} %>
5
  <%= submit_tag l(:button_create) %>
6
<% end %>
.svn/pristine/09/09fd6db0926bf35a4db846796898a3efe70dfa6f.svn-base
1
<table class="list transitions-<%= name %>">
2
<thead>
3
  <tr>
4
    <th align="left">
5
      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input')",
6
                                                          :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
7
      <%=l(:label_current_status)%>
8
    </th>
9
    <th align="center" colspan="<%= @statuses.length %>"><%=l(:label_new_statuses_allowed)%></th>
10
  </tr>
11
  <tr>
12
    <td></td>
13
    <% for new_status in @statuses %>
14
    <td width="<%= 75 / @statuses.size %>%" align="center">
15
      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.new-status-#{new_status.id}')",
16
                                                      :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
17
      <%=h new_status.name %>
18
    </td>
19
    <% end %>
20
  </tr>
21
</thead>
22
<tbody>
23
  <% for old_status in @statuses %>
24
  <tr class="<%= cycle("odd", "even") %>">
25
    <td>
26
      <%= link_to_function(image_tag('toggle_check.png'), "toggleCheckboxesBySelector('table.transitions-#{name} input.old-status-#{old_status.id}')",
27
                                                          :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}") %>
28

  
29
      <%=h old_status.name %>
30
    </td>
31
    <% for new_status in @statuses -%>
32
    <td align="center">
33
      <%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id},
34
            :class => "old-status-#{old_status.id} new-status-#{new_status.id}" %>
35
    </td>
36
    <% end -%>
37
  </tr>
38
  <% end %>
39
</tbody>
40
</table>

Also available in: Unified diff