##// END OF EJS Templates
Added mail notification when a new message is posted in the forums....
Jean-Philippe Lang -
r528:7ca7e4bad503
parent child
Show More
@@ -0,0 +1,24
1 # redMine - project management software
2 # Copyright (C) 2006-2007 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 MessageObserver < ActiveRecord::Observer
19 def after_create(message)
20 # send notification to board watchers
21 recipients = message.board.watcher_recipients
22 Mailer.deliver_message_posted(message, recipients) unless recipients.empty?
23 end
24 end
@@ -0,0 +1,4
1 <%= l(:field_author) %>: <%= @message.author.name %>
2 <%= url_for :only_path => false, :host => Setting.host_name, :controller => 'messages', :action => 'show', :board_id => @message.board_id, :id => @message.root %>
3
4 <%= @message.content %>
@@ -1,90 +1,98
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 IssuesHelper
19 helper IssuesHelper
20
20
21 def issue_add(issue)
21 def issue_add(issue)
22 set_language_if_valid(Setting.default_language)
22 set_language_if_valid(Setting.default_language)
23 # Sends to all project members
23 # Sends to all project members
24 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
24 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
25 @from = Setting.mail_from
25 @from = Setting.mail_from
26 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
26 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
27 @body['issue'] = issue
27 @body['issue'] = issue
28 end
28 end
29
29
30 def issue_edit(journal)
30 def issue_edit(journal)
31 set_language_if_valid(Setting.default_language)
31 set_language_if_valid(Setting.default_language)
32 # Sends to all project members
32 # Sends to all project members
33 issue = journal.journalized
33 issue = journal.journalized
34 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
34 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }.compact
35 # Watchers in cc
35 # Watchers in cc
36 @cc = issue.watcher_recipients - @recipients
36 @cc = issue.watcher_recipients - @recipients
37 @from = Setting.mail_from
37 @from = Setting.mail_from
38 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
38 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
39 @body['issue'] = issue
39 @body['issue'] = issue
40 @body['journal']= journal
40 @body['journal']= journal
41 end
41 end
42
42
43 def document_add(document)
43 def document_add(document)
44 set_language_if_valid(Setting.default_language)
44 set_language_if_valid(Setting.default_language)
45 @recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
45 @recipients = document.project.users.collect { |u| u.mail if u.mail_notification }.compact
46 @from = Setting.mail_from
46 @from = Setting.mail_from
47 @subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
47 @subject = "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
48 @body['document'] = document
48 @body['document'] = document
49 end
49 end
50
50
51 def attachments_add(attachments)
51 def attachments_add(attachments)
52 set_language_if_valid(Setting.default_language)
52 set_language_if_valid(Setting.default_language)
53 container = attachments.first.container
53 container = attachments.first.container
54 url = "http://#{Setting.host_name}/"
54 url = "http://#{Setting.host_name}/"
55 added_to = ""
55 added_to = ""
56 case container.class.to_s
56 case container.class.to_s
57 when 'Version'
57 when 'Version'
58 url << "projects/list_files/#{container.project_id}"
58 url << "projects/list_files/#{container.project_id}"
59 added_to = "#{l(:label_version)}: #{container.name}"
59 added_to = "#{l(:label_version)}: #{container.name}"
60 when 'Document'
60 when 'Document'
61 url << "documents/show/#{container.id}"
61 url << "documents/show/#{container.id}"
62 added_to = "#{l(:label_document)}: #{container.title}"
62 added_to = "#{l(:label_document)}: #{container.title}"
63 when 'Issue'
63 when 'Issue'
64 url << "issues/show/#{container.id}"
64 url << "issues/show/#{container.id}"
65 added_to = "#{container.tracker.name} ##{container.id}: #{container.subject}"
65 added_to = "#{container.tracker.name} ##{container.id}: #{container.subject}"
66 end
66 end
67 @recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
67 @recipients = container.project.users.collect { |u| u.mail if u.mail_notification }.compact
68 @from = Setting.mail_from
68 @from = Setting.mail_from
69 @subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
69 @subject = "[#{container.project.name}] #{l(:label_attachment_new)}"
70 @body['attachments'] = attachments
70 @body['attachments'] = attachments
71 @body['url'] = url
71 @body['url'] = url
72 @body['added_to'] = added_to
72 @body['added_to'] = added_to
73 end
73 end
74
74
75 def lost_password(token)
75 def lost_password(token)
76 set_language_if_valid(token.user.language)
76 set_language_if_valid(token.user.language)
77 @recipients = token.user.mail
77 @recipients = token.user.mail
78 @from = Setting.mail_from
78 @from = Setting.mail_from
79 @subject = l(:mail_subject_lost_password)
79 @subject = l(:mail_subject_lost_password)
80 @body['token'] = token
80 @body['token'] = token
81 end
81 end
82
82
83 def register(token)
83 def register(token)
84 set_language_if_valid(token.user.language)
84 set_language_if_valid(token.user.language)
85 @recipients = token.user.mail
85 @recipients = token.user.mail
86 @from = Setting.mail_from
86 @from = Setting.mail_from
87 @subject = l(:mail_subject_register)
87 @subject = l(:mail_subject_register)
88 @body['token'] = token
88 @body['token'] = token
89 end
89 end
90
91 def message_posted(message, recipients)
92 set_language_if_valid(Setting.default_language)
93 @recipients = recipients
94 @from = Setting.mail_from
95 @subject = "[#{message.board.project.name} - #{message.board.name}] #{message.subject}"
96 @body['message'] = message
97 end
90 end
98 end
@@ -1,86 +1,87
1 # Be sure to restart your web server when you modify this file.
1 # Be sure to restart your web server when you modify this file.
2
2
3 # Uncomment below to force Rails into production mode when
3 # Uncomment below to force Rails into production mode when
4 # you don't control web/app server and can't set it the proper way
4 # you don't control web/app server and can't set it the proper way
5 # ENV['RAILS_ENV'] ||= 'production'
5 # ENV['RAILS_ENV'] ||= 'production'
6
6
7 # Bootstrap the Rails environment, frameworks, and default configuration
7 # Bootstrap the Rails environment, frameworks, and default configuration
8 require File.join(File.dirname(__FILE__), 'boot')
8 require File.join(File.dirname(__FILE__), 'boot')
9
9
10 Rails::Initializer.run do |config|
10 Rails::Initializer.run do |config|
11 # Settings in config/environments/* take precedence those specified here
11 # Settings in config/environments/* take precedence those specified here
12
12
13 # Skip frameworks you're not going to use
13 # Skip frameworks you're not going to use
14 # config.frameworks -= [ :action_web_service, :action_mailer ]
14 # config.frameworks -= [ :action_web_service, :action_mailer ]
15
15
16 # Add additional load paths for sweepers
16 # Add additional load paths for sweepers
17 config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
17 config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
18
18
19 # Force all environments to use the same logger level
19 # Force all environments to use the same logger level
20 # (by default production uses :info, the others :debug)
20 # (by default production uses :info, the others :debug)
21 # config.log_level = :debug
21 # config.log_level = :debug
22
22
23 # Use the database for sessions instead of the file system
23 # Use the database for sessions instead of the file system
24 # (create the session table with 'rake create_sessions_table')
24 # (create the session table with 'rake create_sessions_table')
25 # config.action_controller.session_store = :active_record_store
25 # config.action_controller.session_store = :active_record_store
26
26
27 # Enable page/fragment caching by setting a file-based store
27 # Enable page/fragment caching by setting a file-based store
28 # (remember to create the caching directory and make it readable to the application)
28 # (remember to create the caching directory and make it readable to the application)
29 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
29 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
30
30
31 # Activate observers that should always be running
31 # Activate observers that should always be running
32 # config.active_record.observers = :cacher, :garbage_collector
32 # config.active_record.observers = :cacher, :garbage_collector
33 config.active_record.observers = :message_observer
33
34
34 # Make Active Record use UTC-base instead of local time
35 # Make Active Record use UTC-base instead of local time
35 # config.active_record.default_timezone = :utc
36 # config.active_record.default_timezone = :utc
36
37
37 # Use Active Record's schema dumper instead of SQL when creating the test database
38 # Use Active Record's schema dumper instead of SQL when creating the test database
38 # (enables use of different database adapters for development and test environments)
39 # (enables use of different database adapters for development and test environments)
39 # config.active_record.schema_format = :ruby
40 # config.active_record.schema_format = :ruby
40
41
41 # See Rails::Configuration for more options
42 # See Rails::Configuration for more options
42
43
43 # SMTP server configuration
44 # SMTP server configuration
44 config.action_mailer.smtp_settings = {
45 config.action_mailer.smtp_settings = {
45 :address => "127.0.0.1",
46 :address => "127.0.0.1",
46 :port => 25,
47 :port => 25,
47 :domain => "somenet.foo",
48 :domain => "somenet.foo",
48 :authentication => :login,
49 :authentication => :login,
49 :user_name => "redmine",
50 :user_name => "redmine",
50 :password => "redmine",
51 :password => "redmine",
51 }
52 }
52
53
53 config.action_mailer.perform_deliveries = true
54 config.action_mailer.perform_deliveries = true
54
55
55 # Tell ActionMailer not to deliver emails to the real world.
56 # Tell ActionMailer not to deliver emails to the real world.
56 # The :test delivery method accumulates sent emails in the
57 # The :test delivery method accumulates sent emails in the
57 # ActionMailer::Base.deliveries array.
58 # ActionMailer::Base.deliveries array.
58 #config.action_mailer.delivery_method = :test
59 #config.action_mailer.delivery_method = :test
59 config.action_mailer.delivery_method = :smtp
60 config.action_mailer.delivery_method = :smtp
60 end
61 end
61
62
62 ActiveRecord::Errors.default_error_messages = {
63 ActiveRecord::Errors.default_error_messages = {
63 :inclusion => "activerecord_error_inclusion",
64 :inclusion => "activerecord_error_inclusion",
64 :exclusion => "activerecord_error_exclusion",
65 :exclusion => "activerecord_error_exclusion",
65 :invalid => "activerecord_error_invalid",
66 :invalid => "activerecord_error_invalid",
66 :confirmation => "activerecord_error_confirmation",
67 :confirmation => "activerecord_error_confirmation",
67 :accepted => "activerecord_error_accepted",
68 :accepted => "activerecord_error_accepted",
68 :empty => "activerecord_error_empty",
69 :empty => "activerecord_error_empty",
69 :blank => "activerecord_error_blank",
70 :blank => "activerecord_error_blank",
70 :too_long => "activerecord_error_too_long",
71 :too_long => "activerecord_error_too_long",
71 :too_short => "activerecord_error_too_short",
72 :too_short => "activerecord_error_too_short",
72 :wrong_length => "activerecord_error_wrong_length",
73 :wrong_length => "activerecord_error_wrong_length",
73 :taken => "activerecord_error_taken",
74 :taken => "activerecord_error_taken",
74 :not_a_number => "activerecord_error_not_a_number"
75 :not_a_number => "activerecord_error_not_a_number"
75 }
76 }
76
77
77 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
78 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
78
79
79 GLoc.set_config :default_language => :en
80 GLoc.set_config :default_language => :en
80 GLoc.clear_strings
81 GLoc.clear_strings
81 GLoc.set_kcode
82 GLoc.set_kcode
82 GLoc.load_localized_strings
83 GLoc.load_localized_strings
83 GLoc.set_config(:raise_string_not_found_errors => false)
84 GLoc.set_config(:raise_string_not_found_errors => false)
84
85
85 require 'redmine'
86 require 'redmine'
86
87
@@ -1,230 +1,231
1 # Copyright (c) 2005-2006 David Barri
1 # Copyright (c) 2005-2006 David Barri
2
2
3 require 'gloc'
3 require 'gloc'
4
4
5 module ActionController #:nodoc:
5 module ActionController #:nodoc:
6 class Base #:nodoc:
6 class Base #:nodoc:
7 include GLoc
7 include GLoc
8 end
8 end
9 module Filters #:nodoc:
9 module Filters #:nodoc:
10 module ClassMethods
10 module ClassMethods
11
11
12 # This filter attempts to auto-detect the clients desired language.
12 # This filter attempts to auto-detect the clients desired language.
13 # It first checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE
13 # It first checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE
14 # request header. If a language is found to match or be similar to a currently
14 # request header. If a language is found to match or be similar to a currently
15 # valid language, then it sets the current_language of the controller.
15 # valid language, then it sets the current_language of the controller.
16 #
16 #
17 # class ExampleController < ApplicationController
17 # class ExampleController < ApplicationController
18 # set_language :en
18 # set_language :en
19 # autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
19 # autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
20 # autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
20 # autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
21 # ...
21 # ...
22 # def lang_not_autodetected_callback
22 # def lang_not_autodetected_callback
23 # redirect_to somewhere
23 # redirect_to somewhere
24 # end
24 # end
25 # end
25 # end
26 #
26 #
27 # The <tt>args</tt> for this filter are exactly the same the arguments of
27 # The <tt>args</tt> for this filter are exactly the same the arguments of
28 # <tt>before_filter</tt> with the following exceptions:
28 # <tt>before_filter</tt> with the following exceptions:
29 # * <tt>:check_params</tt> -- If false, then params will not be checked for a language.
29 # * <tt>:check_params</tt> -- If false, then params will not be checked for a language.
30 # If a String, then this will value will be used as the name of the param.
30 # If a String, then this will value will be used as the name of the param.
31 # * <tt>:check_cookie</tt> -- If false, then the cookie will not be checked for a language.
31 # * <tt>:check_cookie</tt> -- If false, then the cookie will not be checked for a language.
32 # If a String, then this will value will be used as the name of the cookie.
32 # If a String, then this will value will be used as the name of the cookie.
33 # * <tt>:check_accept_header</tt> -- If false, then HTTP_ACCEPT_LANGUAGE will not be checked for a language.
33 # * <tt>:check_accept_header</tt> -- If false, then HTTP_ACCEPT_LANGUAGE will not be checked for a language.
34 # * <tt>:on_set_lang</tt> -- You can specify the name of a callback function to be called when the language
34 # * <tt>:on_set_lang</tt> -- You can specify the name of a callback function to be called when the language
35 # is successfully detected and set. The param must be a Symbol or a String which is the name of the function.
35 # is successfully detected and set. The param must be a Symbol or a String which is the name of the function.
36 # The callback function must accept one argument (the language) and must be instance level.
36 # The callback function must accept one argument (the language) and must be instance level.
37 # * <tt>:on_no_lang</tt> -- You can specify the name of a callback function to be called when the language
37 # * <tt>:on_no_lang</tt> -- You can specify the name of a callback function to be called when the language
38 # couldn't be detected automatically. The param must be a Symbol or a String which is the name of the function.
38 # couldn't be detected automatically. The param must be a Symbol or a String which is the name of the function.
39 # The callback function must be instance level.
39 # The callback function must be instance level.
40 #
40 #
41 # You override the default names of the param or cookie by calling <tt>GLoc.set_config :default_param_name => 'new_param_name'</tt>
41 # You override the default names of the param or cookie by calling <tt>GLoc.set_config :default_param_name => 'new_param_name'</tt>
42 # and <tt>GLoc.set_config :default_cookie_name => 'new_cookie_name'</tt>.
42 # and <tt>GLoc.set_config :default_cookie_name => 'new_cookie_name'</tt>.
43 def autodetect_language_filter(*args)
43 def autodetect_language_filter(*args)
44 options= args.last.is_a?(Hash) ? args.last : {}
44 options= args.last.is_a?(Hash) ? args.last : {}
45 x= 'Proc.new { |c| l= nil;'
45 x= 'Proc.new { |c| l= nil;'
46 # :check_params
46 # :check_params
47 unless (v= options.delete(:check_params)) == false
47 unless (v= options.delete(:check_params)) == false
48 name= v ? ":#{v}" : 'GLoc.get_config(:default_param_name)'
48 name= v ? ":#{v}" : 'GLoc.get_config(:default_param_name)'
49 x << "l ||= GLoc.similar_language(c.params[#{name}]);"
49 x << "l ||= GLoc.similar_language(c.params[#{name}]);"
50 end
50 end
51 # :check_cookie
51 # :check_cookie
52 unless (v= options.delete(:check_cookie)) == false
52 unless (v= options.delete(:check_cookie)) == false
53 name= v ? ":#{v}" : 'GLoc.get_config(:default_cookie_name)'
53 name= v ? ":#{v}" : 'GLoc.get_config(:default_cookie_name)'
54 x << "l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"
54 x << "l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"
55 end
55 end
56 # :check_accept_header
56 # :check_accept_header
57 unless options.delete(:check_accept_header) == false
57 unless options.delete(:check_accept_header) == false
58 x << %<
58 x << %<
59 unless l
59 unless l
60 a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
60 a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
61 a.each {|x| l ||= GLoc.similar_language(x)} if a
61 a.each {|x| l ||= GLoc.similar_language(x)} if a
62 end; >
62 end; >
63 end
63 end
64 # Set language
64 # Set language
65 x << 'ret= true;'
65 x << 'ret= true;'
66 x << 'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '
66 x << 'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '
67 if options.has_key?(:on_set_lang)
67 if options.has_key?(:on_set_lang)
68 x << "ret= c.#{options.delete(:on_set_lang)}(l);"
68 x << "ret= c.#{options.delete(:on_set_lang)}(l);"
69 end
69 end
70 if options.has_key?(:on_no_lang)
70 if options.has_key?(:on_no_lang)
71 x << "else; ret= c.#{options.delete(:on_no_lang)};"
71 x << "else; ret= c.#{options.delete(:on_no_lang)};"
72 end
72 end
73 x << 'end; ret }'
73 x << 'end; ret }'
74
74
75 # Create filter
75 # Create filter
76 block= eval x
76 block= eval x
77 before_filter(*args, &block)
77 before_filter(*args, &block)
78 end
78 end
79
79
80 end
80 end
81 end
81 end
82 end
82 end
83
83
84 # ==============================================================================
84 # ==============================================================================
85
85
86 module ActionMailer #:nodoc:
86 module ActionMailer #:nodoc:
87 # In addition to including GLoc, <tt>render_message</tt> is also overridden so
87 # In addition to including GLoc, <tt>render_message</tt> is also overridden so
88 # that mail templates contain the current language at the end of the file.
88 # that mail templates contain the current language at the end of the file.
89 # Eg. <tt>deliver_hello</tt> will render <tt>hello_en.rhtml</tt>.
89 # Eg. <tt>deliver_hello</tt> will render <tt>hello_en.rhtml</tt>.
90 class Base
90 class Base
91 include GLoc
91 include GLoc
92 private
92 private
93 alias :render_message_without_gloc :render_message
93 alias :render_message_without_gloc :render_message
94 def render_message(method_name, body)
94 def render_message(method_name, body)
95 render_message_without_gloc("#{method_name}_#{current_language}", body)
95 template = File.exist?("#{template_path}/#{method_name}_#{current_language}.rhtml") ? "#{method_name}_#{current_language}" : "#{method_name}"
96 render_message_without_gloc(template, body)
96 end
97 end
97 end
98 end
98 end
99 end
99
100
100 # ==============================================================================
101 # ==============================================================================
101
102
102 module ActionView #:nodoc:
103 module ActionView #:nodoc:
103 # <tt>initialize</tt> is overridden so that new instances of this class inherit
104 # <tt>initialize</tt> is overridden so that new instances of this class inherit
104 # the current language of the controller.
105 # the current language of the controller.
105 class Base
106 class Base
106 include GLoc
107 include GLoc
107
108
108 alias :initialize_without_gloc :initialize
109 alias :initialize_without_gloc :initialize
109 def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)
110 def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)
110 initialize_without_gloc(base_path, assigns_for_first_render, controller)
111 initialize_without_gloc(base_path, assigns_for_first_render, controller)
111 set_language controller.current_language unless controller.nil?
112 set_language controller.current_language unless controller.nil?
112 end
113 end
113 end
114 end
114
115
115 module Helpers #:nodoc:
116 module Helpers #:nodoc:
116 class InstanceTag
117 class InstanceTag
117 include GLoc
118 include GLoc
118 # Inherits the current language from the template object.
119 # Inherits the current language from the template object.
119 def current_language
120 def current_language
120 @template_object.current_language
121 @template_object.current_language
121 end
122 end
122 end
123 end
123 end
124 end
124 end
125 end
125
126
126 # ==============================================================================
127 # ==============================================================================
127
128
128 module ActiveRecord #:nodoc:
129 module ActiveRecord #:nodoc:
129 class Base #:nodoc:
130 class Base #:nodoc:
130 include GLoc
131 include GLoc
131 end
132 end
132
133
133 # class Errors
134 # class Errors
134 # include GLoc
135 # include GLoc
135 # alias :add_without_gloc :add
136 # alias :add_without_gloc :add
136 # # The GLoc version of this method provides two extra features
137 # # The GLoc version of this method provides two extra features
137 # # * If <tt>msg</tt> is a string, it will be considered a GLoc string key.
138 # # * If <tt>msg</tt> is a string, it will be considered a GLoc string key.
138 # # * If <tt>msg</tt> is an array, the first element will be considered
139 # # * If <tt>msg</tt> is an array, the first element will be considered
139 # # the string and the remaining elements will be considered arguments for the
140 # # the string and the remaining elements will be considered arguments for the
140 # # string. Eg. <tt>['Hi %s.','John']</tt>
141 # # string. Eg. <tt>['Hi %s.','John']</tt>
141 # def add(attribute, msg= @@default_error_messages[:invalid])
142 # def add(attribute, msg= @@default_error_messages[:invalid])
142 # if msg.is_a?(Array)
143 # if msg.is_a?(Array)
143 # args= msg.clone
144 # args= msg.clone
144 # msg= args.shift
145 # msg= args.shift
145 # args= nil if args.empty?
146 # args= nil if args.empty?
146 # end
147 # end
147 # msg= ltry(msg)
148 # msg= ltry(msg)
148 # msg= msg % args unless args.nil?
149 # msg= msg % args unless args.nil?
149 # add_without_gloc(attribute, msg)
150 # add_without_gloc(attribute, msg)
150 # end
151 # end
151 # # Inherits the current language from the base record.
152 # # Inherits the current language from the base record.
152 # def current_language
153 # def current_language
153 # @base.current_language
154 # @base.current_language
154 # end
155 # end
155 # end
156 # end
156
157
157 module Validations #:nodoc:
158 module Validations #:nodoc:
158 module ClassMethods
159 module ClassMethods
159 # The default Rails version of this function creates an error message and then
160 # The default Rails version of this function creates an error message and then
160 # passes it to ActiveRecord.Errors.
161 # passes it to ActiveRecord.Errors.
161 # The GLoc version of this method, sends an array to ActiveRecord.Errors that will
162 # The GLoc version of this method, sends an array to ActiveRecord.Errors that will
162 # be turned into a string by ActiveRecord.Errors which in turn allows for the message
163 # be turned into a string by ActiveRecord.Errors which in turn allows for the message
163 # of this validation function to be a GLoc string key.
164 # of this validation function to be a GLoc string key.
164 def validates_length_of(*attrs)
165 def validates_length_of(*attrs)
165 # Merge given options with defaults.
166 # Merge given options with defaults.
166 options = {
167 options = {
167 :too_long => ActiveRecord::Errors.default_error_messages[:too_long],
168 :too_long => ActiveRecord::Errors.default_error_messages[:too_long],
168 :too_short => ActiveRecord::Errors.default_error_messages[:too_short],
169 :too_short => ActiveRecord::Errors.default_error_messages[:too_short],
169 :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
170 :wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
170 }.merge(DEFAULT_VALIDATION_OPTIONS)
171 }.merge(DEFAULT_VALIDATION_OPTIONS)
171 options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
172 options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
172
173
173 # Ensure that one and only one range option is specified.
174 # Ensure that one and only one range option is specified.
174 range_options = ALL_RANGE_OPTIONS & options.keys
175 range_options = ALL_RANGE_OPTIONS & options.keys
175 case range_options.size
176 case range_options.size
176 when 0
177 when 0
177 raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
178 raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
178 when 1
179 when 1
179 # Valid number of options; do nothing.
180 # Valid number of options; do nothing.
180 else
181 else
181 raise ArgumentError, 'Too many range options specified. Choose only one.'
182 raise ArgumentError, 'Too many range options specified. Choose only one.'
182 end
183 end
183
184
184 # Get range option and value.
185 # Get range option and value.
185 option = range_options.first
186 option = range_options.first
186 option_value = options[range_options.first]
187 option_value = options[range_options.first]
187
188
188 case option
189 case option
189 when :within, :in
190 when :within, :in
190 raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
191 raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
191
192
192 too_short = [options[:too_short] , option_value.begin]
193 too_short = [options[:too_short] , option_value.begin]
193 too_long = [options[:too_long] , option_value.end ]
194 too_long = [options[:too_long] , option_value.end ]
194
195
195 validates_each(attrs, options) do |record, attr, value|
196 validates_each(attrs, options) do |record, attr, value|
196 if value.nil? or value.split(//).size < option_value.begin
197 if value.nil? or value.split(//).size < option_value.begin
197 record.errors.add(attr, too_short)
198 record.errors.add(attr, too_short)
198 elsif value.split(//).size > option_value.end
199 elsif value.split(//).size > option_value.end
199 record.errors.add(attr, too_long)
200 record.errors.add(attr, too_long)
200 end
201 end
201 end
202 end
202 when :is, :minimum, :maximum
203 when :is, :minimum, :maximum
203 raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
204 raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
204
205
205 # Declare different validations per option.
206 # Declare different validations per option.
206 validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
207 validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
207 message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
208 message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
208
209
209 message = [(options[:message] || options[message_options[option]]) , option_value]
210 message = [(options[:message] || options[message_options[option]]) , option_value]
210
211
211 validates_each(attrs, options) do |record, attr, value|
212 validates_each(attrs, options) do |record, attr, value|
212 if value.kind_of?(String)
213 if value.kind_of?(String)
213 record.errors.add(attr, message) unless !value.nil? and value.split(//).size.method(validity_checks[option])[option_value]
214 record.errors.add(attr, message) unless !value.nil? and value.split(//).size.method(validity_checks[option])[option_value]
214 else
215 else
215 record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
216 record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
216 end
217 end
217 end
218 end
218 end
219 end
219 end
220 end
220
221
221 alias_method :validates_size_of, :validates_length_of
222 alias_method :validates_size_of, :validates_length_of
222 end
223 end
223 end
224 end
224 end
225 end
225
226
226 # ==============================================================================
227 # ==============================================================================
227
228
228 module ApplicationHelper #:nodoc:
229 module ApplicationHelper #:nodoc:
229 include GLoc
230 include GLoc
230 end
231 end
General Comments 0
You need to be logged in to leave comments. Login now