976a31e941
The 'Change status' specific form removed and now accessible from issue/show view with no additional request (click on 'Update' to show the form). The 'Change issue status' permission is removed. To change the status, the user just needs to have either 'Edit' or 'Add note' permissions and some workflow transitions allowed. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1043 e93f8b46-1217-0410-a6f0-8f06a7374b81
253 lines
10 KiB
Ruby
253 lines
10 KiB
Ruby
# Copyright (c) 2005-2006 David Barri
|
|
|
|
require 'gloc'
|
|
|
|
module ActionController #:nodoc:
|
|
class Base #:nodoc:
|
|
include GLoc
|
|
end
|
|
module Filters #:nodoc:
|
|
module ClassMethods
|
|
|
|
# This filter attempts to auto-detect the clients desired language.
|
|
# It first checks the params, then a cookie and then the HTTP_ACCEPT_LANGUAGE
|
|
# request header. If a language is found to match or be similar to a currently
|
|
# valid language, then it sets the current_language of the controller.
|
|
#
|
|
# class ExampleController < ApplicationController
|
|
# set_language :en
|
|
# autodetect_language_filter :except => 'monkey', :on_no_lang => :lang_not_autodetected_callback
|
|
# autodetect_language_filter :only => 'monkey', :check_cookie => 'monkey_lang', :check_accept_header => false
|
|
# ...
|
|
# def lang_not_autodetected_callback
|
|
# redirect_to somewhere
|
|
# end
|
|
# end
|
|
#
|
|
# The <tt>args</tt> for this filter are exactly the same the arguments of
|
|
# <tt>before_filter</tt> with the following exceptions:
|
|
# * <tt>:check_params</tt> -- If false, then params will not be checked for a language.
|
|
# If a String, then this will value will be used as the name of the param.
|
|
# * <tt>:check_cookie</tt> -- If false, then the cookie will not be checked for a language.
|
|
# If a String, then this will value will be used as the name of the cookie.
|
|
# * <tt>:check_accept_header</tt> -- If false, then HTTP_ACCEPT_LANGUAGE will not be checked for a language.
|
|
# * <tt>:on_set_lang</tt> -- You can specify the name of a callback function to be called when the language
|
|
# is successfully detected and set. The param must be a Symbol or a String which is the name of the function.
|
|
# The callback function must accept one argument (the language) and must be instance level.
|
|
# * <tt>:on_no_lang</tt> -- You can specify the name of a callback function to be called when the language
|
|
# couldn't be detected automatically. The param must be a Symbol or a String which is the name of the function.
|
|
# The callback function must be instance level.
|
|
#
|
|
# You override the default names of the param or cookie by calling <tt>GLoc.set_config :default_param_name => 'new_param_name'</tt>
|
|
# and <tt>GLoc.set_config :default_cookie_name => 'new_cookie_name'</tt>.
|
|
def autodetect_language_filter(*args)
|
|
options= args.last.is_a?(Hash) ? args.last : {}
|
|
x= 'Proc.new { |c| l= nil;'
|
|
# :check_params
|
|
unless (v= options.delete(:check_params)) == false
|
|
name= v ? ":#{v}" : 'GLoc.get_config(:default_param_name)'
|
|
x << "l ||= GLoc.similar_language(c.params[#{name}]);"
|
|
end
|
|
# :check_cookie
|
|
unless (v= options.delete(:check_cookie)) == false
|
|
name= v ? ":#{v}" : 'GLoc.get_config(:default_cookie_name)'
|
|
x << "l ||= GLoc.similar_language(c.send(:cookies)[#{name}]);"
|
|
end
|
|
# :check_accept_header
|
|
unless options.delete(:check_accept_header) == false
|
|
x << %<
|
|
unless l
|
|
a= c.request.env['HTTP_ACCEPT_LANGUAGE'].split(/,|;/) rescue nil
|
|
a.each {|x| l ||= GLoc.similar_language(x)} if a
|
|
end; >
|
|
end
|
|
# Set language
|
|
x << 'ret= true;'
|
|
x << 'if l; c.set_language(l); c.headers[\'Content-Language\']= l.to_s; '
|
|
if options.has_key?(:on_set_lang)
|
|
x << "ret= c.#{options.delete(:on_set_lang)}(l);"
|
|
end
|
|
if options.has_key?(:on_no_lang)
|
|
x << "else; ret= c.#{options.delete(:on_no_lang)};"
|
|
end
|
|
x << 'end; ret }'
|
|
|
|
# Create filter
|
|
block= eval x
|
|
before_filter(*args, &block)
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
# ==============================================================================
|
|
|
|
module ActionMailer #:nodoc:
|
|
# In addition to including GLoc, <tt>render_message</tt> is also overridden so
|
|
# that mail templates contain the current language at the end of the file.
|
|
# Eg. <tt>deliver_hello</tt> will render <tt>hello_en.rhtml</tt>.
|
|
class Base
|
|
include GLoc
|
|
private
|
|
alias :render_message_without_gloc :render_message
|
|
def render_message(method_name, body)
|
|
template = File.exist?("#{template_path}/#{method_name}_#{current_language}.rhtml") ? "#{method_name}_#{current_language}" : "#{method_name}"
|
|
render_message_without_gloc(template, body)
|
|
end
|
|
end
|
|
end
|
|
|
|
# ==============================================================================
|
|
|
|
module ActionView #:nodoc:
|
|
# <tt>initialize</tt> is overridden so that new instances of this class inherit
|
|
# the current language of the controller.
|
|
class Base
|
|
include GLoc
|
|
|
|
alias :initialize_without_gloc :initialize
|
|
def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)
|
|
initialize_without_gloc(base_path, assigns_for_first_render, controller)
|
|
set_language controller.current_language unless controller.nil?
|
|
end
|
|
end
|
|
|
|
module Helpers #:nodoc:
|
|
class InstanceTag
|
|
include GLoc
|
|
# Inherits the current language from the template object.
|
|
def current_language
|
|
@template_object.current_language
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# ==============================================================================
|
|
|
|
module ActiveRecord #:nodoc:
|
|
class Base #:nodoc:
|
|
include GLoc
|
|
end
|
|
|
|
# class Errors
|
|
# include GLoc
|
|
# alias :add_without_gloc :add
|
|
# # The GLoc version of this method provides two extra features
|
|
# # * If <tt>msg</tt> is a string, it will be considered a GLoc string key.
|
|
# # * If <tt>msg</tt> is an array, the first element will be considered
|
|
# # the string and the remaining elements will be considered arguments for the
|
|
# # string. Eg. <tt>['Hi %s.','John']</tt>
|
|
# def add(attribute, msg= @@default_error_messages[:invalid])
|
|
# if msg.is_a?(Array)
|
|
# args= msg.clone
|
|
# msg= args.shift
|
|
# args= nil if args.empty?
|
|
# end
|
|
# msg= ltry(msg)
|
|
# msg= msg % args unless args.nil?
|
|
# add_without_gloc(attribute, msg)
|
|
# end
|
|
# # Inherits the current language from the base record.
|
|
# def current_language
|
|
# @base.current_language
|
|
# end
|
|
# end
|
|
|
|
class Errors
|
|
include GLoc
|
|
|
|
def full_messages
|
|
full_messages = []
|
|
|
|
@errors.each_key do |attr|
|
|
@errors[attr].each do |msg|
|
|
next if msg.nil?
|
|
|
|
if attr == "base"
|
|
full_messages << (msg.is_a?(Symbol) ? l(msg) : msg)
|
|
else
|
|
full_messages << @base.class.human_attribute_name(attr) + " " + (msg.is_a?(Symbol) ? l(msg) : msg)
|
|
end
|
|
end
|
|
end
|
|
full_messages
|
|
end
|
|
end
|
|
|
|
module Validations #:nodoc:
|
|
module ClassMethods
|
|
# The default Rails version of this function creates an error message and then
|
|
# passes it to ActiveRecord.Errors.
|
|
# The GLoc version of this method, sends an array to ActiveRecord.Errors that will
|
|
# be turned into a string by ActiveRecord.Errors which in turn allows for the message
|
|
# of this validation function to be a GLoc string key.
|
|
def validates_length_of(*attrs)
|
|
# Merge given options with defaults.
|
|
options = {
|
|
:too_long => ActiveRecord::Errors.default_error_messages[:too_long],
|
|
:too_short => ActiveRecord::Errors.default_error_messages[:too_short],
|
|
:wrong_length => ActiveRecord::Errors.default_error_messages[:wrong_length]
|
|
}.merge(DEFAULT_VALIDATION_OPTIONS)
|
|
options.update(attrs.pop.symbolize_keys) if attrs.last.is_a?(Hash)
|
|
|
|
# Ensure that one and only one range option is specified.
|
|
range_options = ALL_RANGE_OPTIONS & options.keys
|
|
case range_options.size
|
|
when 0
|
|
raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
|
|
when 1
|
|
# Valid number of options; do nothing.
|
|
else
|
|
raise ArgumentError, 'Too many range options specified. Choose only one.'
|
|
end
|
|
|
|
# Get range option and value.
|
|
option = range_options.first
|
|
option_value = options[range_options.first]
|
|
|
|
case option
|
|
when :within, :in
|
|
raise ArgumentError, ":#{option} must be a Range" unless option_value.is_a?(Range)
|
|
|
|
too_short = [options[:too_short] , option_value.begin]
|
|
too_long = [options[:too_long] , option_value.end ]
|
|
|
|
validates_each(attrs, options) do |record, attr, value|
|
|
if value.nil? or value.split(//).size < option_value.begin
|
|
record.errors.add(attr, too_short)
|
|
elsif value.split(//).size > option_value.end
|
|
record.errors.add(attr, too_long)
|
|
end
|
|
end
|
|
when :is, :minimum, :maximum
|
|
raise ArgumentError, ":#{option} must be a nonnegative Integer" unless option_value.is_a?(Integer) and option_value >= 0
|
|
|
|
# Declare different validations per option.
|
|
validity_checks = { :is => "==", :minimum => ">=", :maximum => "<=" }
|
|
message_options = { :is => :wrong_length, :minimum => :too_short, :maximum => :too_long }
|
|
|
|
message = [(options[:message] || options[message_options[option]]) , option_value]
|
|
|
|
validates_each(attrs, options) do |record, attr, value|
|
|
if value.kind_of?(String)
|
|
record.errors.add(attr, message) unless !value.nil? and value.split(//).size.method(validity_checks[option])[option_value]
|
|
else
|
|
record.errors.add(attr, message) unless !value.nil? and value.size.method(validity_checks[option])[option_value]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
alias_method :validates_size_of, :validates_length_of
|
|
end
|
|
end
|
|
end
|
|
|
|
# ==============================================================================
|
|
|
|
module ApplicationHelper #:nodoc:
|
|
include GLoc
|
|
end
|