You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10-patches.rb 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. # frozen_string_literal: true
  2. module ActiveRecord
  3. # Undefines private Kernel#open method to allow using `open` scopes in models.
  4. # See Defect #11545 (http://www.redmine.org/issues/11545) for details.
  5. class Base
  6. class << self
  7. undef open
  8. end
  9. end
  10. class Relation ; undef open ; end
  11. end
  12. module ActionView
  13. module Helpers
  14. module DateHelper
  15. # distance_of_time_in_words breaks when difference is greater than 30 years
  16. def distance_of_date_in_words(from_date, to_date = 0, options = {})
  17. from_date = from_date.to_date if from_date.respond_to?(:to_date)
  18. to_date = to_date.to_date if to_date.respond_to?(:to_date)
  19. distance_in_days = (to_date - from_date).abs
  20. I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
  21. case distance_in_days
  22. when 0..60 then locale.t :x_days, :count => distance_in_days.round
  23. when 61..720 then locale.t :about_x_months, :count => (distance_in_days / 30).round
  24. else locale.t :over_x_years, :count => (distance_in_days / 365).floor
  25. end
  26. end
  27. end
  28. end
  29. end
  30. end
  31. ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || ''.html_safe }
  32. # HTML5: <option value=""></option> is invalid, use <option value="">&nbsp;</option> instead
  33. module ActionView
  34. module Helpers
  35. module Tags
  36. SelectRenderer.prepend(Module.new do
  37. def add_options(option_tags, options, value = nil)
  38. if options.delete(:include_blank)
  39. options[:prompt] = '&nbsp;'.html_safe
  40. end
  41. super
  42. end
  43. end)
  44. end
  45. module FormHelper
  46. alias :date_field_without_max :date_field
  47. def date_field(object_name, method, options = {})
  48. date_field_without_max(object_name, method, options.reverse_merge(max: '9999-12-31'))
  49. end
  50. end
  51. module FormTagHelper
  52. alias :select_tag_without_non_empty_blank_option :select_tag
  53. def select_tag(name, option_tags = nil, options = {})
  54. if options.delete(:include_blank)
  55. options[:prompt] = '&nbsp;'.html_safe
  56. end
  57. select_tag_without_non_empty_blank_option(name, option_tags, options)
  58. end
  59. alias :date_field_tag_without_max :date_field_tag
  60. def date_field_tag(name, value = nil, options = {})
  61. date_field_tag_without_max(name, value, options.reverse_merge(max: '9999-12-31'))
  62. end
  63. end
  64. module FormOptionsHelper
  65. alias :options_for_select_without_non_empty_blank_option :options_for_select
  66. def options_for_select(container, selected = nil)
  67. if container.is_a?(Array)
  68. container = container.map {|element| element.presence || ["&nbsp;".html_safe, ""]}
  69. end
  70. options_for_select_without_non_empty_blank_option(container, selected)
  71. end
  72. end
  73. end
  74. end
  75. require 'mail'
  76. module DeliveryMethods
  77. class TmpFile
  78. def initialize(*args); end
  79. def deliver!(mail)
  80. dest_dir = File.join(Rails.root, 'tmp', 'emails')
  81. Dir.mkdir(dest_dir) unless File.directory?(dest_dir)
  82. filename = "#{Time.now.to_i}_#{mail.message_id.gsub(/[<>]/, '')}.eml"
  83. File.binwrite(File.join(dest_dir, filename), mail.encoded)
  84. end
  85. end
  86. end
  87. ActionMailer::Base.add_delivery_method :tmp_file, DeliveryMethods::TmpFile
  88. module ActionController
  89. module MimeResponds
  90. class Collector
  91. def api(&block)
  92. any(:xml, :json, &block)
  93. end
  94. end
  95. end
  96. end
  97. module ActionController
  98. class Base
  99. # Displays an explicit message instead of a NoMethodError exception
  100. # when trying to start Redmine with an old session_store.rb
  101. # TODO: remove it in a later version
  102. def self.session=(*args)
  103. $stderr.puts "Please remove config/initializers/session_store.rb and run `rake generate_secret_token`.\n" +
  104. "Setting the session secret with ActionController.session= is no longer supported."
  105. exit 1
  106. end
  107. end
  108. end
  109. module ActionView
  110. LookupContext.prepend(Module.new do
  111. def formats=(values)
  112. if (Array(values) & [:xml, :json]).any?
  113. values << :api
  114. end
  115. super(values)
  116. end
  117. end)
  118. end
  119. module ActionController
  120. Base.prepend(Module.new do
  121. def rendered_format
  122. if lookup_context.formats.first == :api
  123. return request.format
  124. end
  125. super
  126. end
  127. end)
  128. end
  129. Mime::SET << 'api'
  130. # Adds asset_id parameters to assets like Rails 3 to invalidate caches in browser
  131. module ActionView
  132. module Helpers
  133. module AssetUrlHelper
  134. @@cache_asset_timestamps = Rails.env.production?
  135. @@asset_timestamps_cache = {}
  136. @@asset_timestamps_cache_guard = Mutex.new
  137. def asset_path_with_asset_id(source, options = {})
  138. asset_id = rails_asset_id(source, options)
  139. unless asset_id.blank?
  140. source += "?#{asset_id}"
  141. end
  142. asset_path(source, options.merge(skip_pipeline: true))
  143. end
  144. alias :path_to_asset :asset_path_with_asset_id
  145. def rails_asset_id(source, options = {})
  146. if asset_id = ENV["RAILS_ASSET_ID"]
  147. asset_id
  148. else
  149. if @@cache_asset_timestamps && (asset_id = @@asset_timestamps_cache[source])
  150. asset_id
  151. else
  152. extname = compute_asset_extname(source, options)
  153. path = File.join(Rails.public_path, "#{source}#{extname}")
  154. exist = false
  155. if File.exist? path
  156. exist = true
  157. else
  158. path = File.join(Rails.public_path, public_compute_asset_path("#{source}#{extname}", options))
  159. if File.exist? path
  160. exist = true
  161. end
  162. end
  163. asset_id = exist ? File.mtime(path).to_i.to_s : ''
  164. if @@cache_asset_timestamps
  165. @@asset_timestamps_cache_guard.synchronize do
  166. @@asset_timestamps_cache[source] = asset_id
  167. end
  168. end
  169. asset_id
  170. end
  171. end
  172. end
  173. end
  174. end
  175. end