Jean-Philippe Lang 976a31e941 Merged IssuesController change_status and add_note actions.
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
2008-01-06 17:06:14 +00:00

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