setting.rb 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. if ENV['ZAMMAD_SETTING_TTL']
  17. @@lookup_timeout = ENV['ZAMMAD_SETTING_TTL'].to_i # rubocop:disable Style/ClassVars
  18. else
  19. @@lookup_timeout = 2.minutes # rubocop:disable Style/ClassVars
  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. fail "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. fail "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. private
  62. # load values and cache them
  63. def self.load
  64. # check if config is already generated
  65. if @@current[:settings_config]
  66. return false if cache_valid?
  67. end
  68. # read all config settings
  69. config = {}
  70. Setting.select('name, state_current').order(:id).each { |setting|
  71. config[setting.name] = setting.state_current[:value]
  72. }
  73. # config lookups
  74. config.each { |key, value|
  75. next if value.class.to_s != 'String'
  76. config[key].gsub!( /\#\{config\.(.+?)\}/ ) {
  77. config[$1].to_s
  78. }
  79. }
  80. # store for class requests
  81. cache(config)
  82. true
  83. end
  84. # set initial value in state_initial
  85. def set_initial
  86. self.state_initial = state_current
  87. end
  88. # set new cache
  89. def self.cache(config)
  90. @@change_id = Cache.get('Setting::ChangeId') # rubocop:disable Style/ClassVars
  91. @@current[:settings_config] = config
  92. logger.debug "Setting.cache: set cache, #{@@change_id}"
  93. @@lookup_at = Time.zone.now # rubocop:disable Style/ClassVars
  94. end
  95. # reset cache
  96. def reset_cache
  97. @@change_id = rand(999_999_999).to_s # rubocop:disable Style/ClassVars
  98. logger.debug "Setting.reset_cache: set new cache, #{@@change_id}"
  99. Cache.write('Setting::ChangeId', @@change_id, { expires_in: 24.hours })
  100. @@current[:settings_config] = nil
  101. end
  102. # check if cache is still valid
  103. def self.cache_valid?
  104. if @@lookup_at && @@lookup_at > Time.zone.now - @@lookup_timeout
  105. #logger.debug 'Setting.cache_valid?: cache_id has beed set within last 2 minutes'
  106. return true
  107. end
  108. change_id = Cache.get('Setting::ChangeId')
  109. if change_id == @@change_id
  110. @@lookup_at = Time.zone.now # rubocop:disable Style/ClassVars
  111. logger.debug "Setting.cache_valid?: cache still valid, #{@@change_id}/#{change_id}"
  112. return true
  113. end
  114. logger.debug "Setting.cache_valid?: cache has changed, #{@@change_id}/#{change_id}"
  115. false
  116. end
  117. # convert state into hash to be able to store it as store
  118. def state_check
  119. return if !state
  120. return if state && state.respond_to?('has_key?') && state.key?(:value)
  121. self.state_current = { value: state }
  122. end
  123. end