setting.rb 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
  2. class Setting < ApplicationModel
  3. store :options
  4. store :state_current
  5. store :state_initial
  6. store :preferences
  7. before_create :state_check, :set_initial
  8. before_update :state_check
  9. after_create :reset_cache
  10. after_update :reset_cache
  11. after_destroy :reset_cache
  12. attr_accessor :state
  13. @@current = {} # rubocop:disable Style/ClassVars
  14. @@change_id = nil # rubocop:disable Style/ClassVars
  15. @@lookup_at = nil # rubocop:disable Style/ClassVars
  16. @@lookup_timeout = if ENV['ZAMMAD_SETTING_TTL'] # rubocop:disable Style/ClassVars
  17. ENV['ZAMMAD_SETTING_TTL'].to_i.seconds
  18. else
  19. 2.minutes
  20. end
  21. =begin
  22. set config setting
  23. Setting.set('some_config_name', some_value)
  24. =end
  25. def self.set(name, value)
  26. setting = Setting.find_by( name: name )
  27. if !setting
  28. raise "Can't find config setting '#{name}'"
  29. end
  30. setting.state_current = { value: value }
  31. setting.save
  32. logger.info "Setting.set(#{name}, #{value.inspect})"
  33. end
  34. =begin
  35. get config setting
  36. value = Setting.get('some_config_name')
  37. =end
  38. def self.get(name)
  39. if load
  40. logger.debug "Setting.get(#{name.inspect}) # no cache"
  41. else
  42. logger.debug "Setting.get(#{name.inspect}) # from cache"
  43. end
  44. @@current[:settings_config][name]
  45. end
  46. =begin
  47. reset config setting to default
  48. Setting.reset('some_config_name')
  49. =end
  50. def self.reset(name)
  51. setting = Setting.find_by( name: name )
  52. if !setting
  53. raise "Can't find config setting '#{name}'"
  54. end
  55. setting.state_current = setting.state_initial
  56. setting.save
  57. logger.info "Setting.reset(#{name}, #{setting.state_current.inspect})"
  58. load
  59. @@current[:settings_config][name]
  60. end
  61. =begin
  62. reload config settings
  63. Setting.reload
  64. =end
  65. def self.reload
  66. load(true)
  67. end
  68. private
  69. # load values and cache them
  70. def self.load(force = false)
  71. # check if config is already generated
  72. if !force && @@current[:settings_config]
  73. return false if cache_valid?
  74. end
  75. # read all config settings
  76. config = {}
  77. Setting.select('name, state_current').order(:id).each { |setting|
  78. config[setting.name] = setting.state_current[:value]
  79. }
  80. # config lookups
  81. config.each { |key, value|
  82. next if value.class.to_s != 'String'
  83. config[key].gsub!( /\#\{config\.(.+?)\}/ ) {
  84. config[$1].to_s
  85. }
  86. }
  87. # store for class requests
  88. cache(config)
  89. true
  90. end
  91. private_class_method :load
  92. # set initial value in state_initial
  93. def set_initial
  94. self.state_initial = state_current
  95. end
  96. # set new cache
  97. def self.cache(config)
  98. @@change_id = Cache.get('Setting::ChangeId') # rubocop:disable Style/ClassVars
  99. @@current[:settings_config] = config
  100. logger.debug "Setting.cache: set cache, #{@@change_id}"
  101. @@lookup_at = Time.zone.now # rubocop:disable Style/ClassVars
  102. end
  103. private_class_method :cache
  104. # reset cache
  105. def reset_cache
  106. @@change_id = rand(999_999_999).to_s # rubocop:disable Style/ClassVars
  107. logger.debug "Setting.reset_cache: set new cache, #{@@change_id}"
  108. Cache.write('Setting::ChangeId', @@change_id, { expires_in: 24.hours })
  109. @@current[:settings_config] = nil
  110. end
  111. # check if cache is still valid
  112. def self.cache_valid?
  113. if @@lookup_at && @@lookup_at > Time.zone.now - @@lookup_timeout
  114. #logger.debug 'Setting.cache_valid?: cache_id has beed set within last 2 minutes'
  115. return true
  116. end
  117. change_id = Cache.get('Setting::ChangeId')
  118. if change_id == @@change_id
  119. @@lookup_at = Time.zone.now # rubocop:disable Style/ClassVars
  120. logger.debug "Setting.cache_valid?: cache still valid, #{@@change_id}/#{change_id}"
  121. return true
  122. end
  123. logger.debug "Setting.cache_valid?: cache has changed, #{@@change_id}/#{change_id}"
  124. false
  125. end
  126. private_class_method :cache_valid?
  127. # convert state into hash to be able to store it as store
  128. def state_check
  129. return if !state
  130. return if state && state.respond_to?('has_key?') && state.key?(:value)
  131. self.state_current = { value: state }
  132. end
  133. end