-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
setting.rb
99 lines (88 loc) · 3.28 KB
/
setting.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Copyright (c) 2008-2013 Michael Dvorkin and contributors.
#
# Fat Free CRM is freely distributable under the terms of MIT license.
# See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
#------------------------------------------------------------------------------
# == Schema Information
#
# Table name: settings
#
# id :integer not null, primary key
# name :string(32) default(""), not null
# value :text
# created_at :datetime
# updated_at :datetime
#
# Fat Free CRM settings are stored in three places, and are loaded in the following order:
#
# 1) config/settings.default.yml
# 2) config/settings.yml (if exists)
# 3) 'settings' table in database (if exists)
#
# Any configured settings in `config/settings.yml` will override those in
# `config/settings.default.yml`, and settings in the database table have the highest priority.
class Setting < ActiveRecord::Base
serialize :value
# Use class variables for cache and yaml settings.
cattr_accessor :cache, :yaml_settings
@@cache = @@yaml_settings = {}.with_indifferent_access
class << self
# Cache should be cleared before each request.
def clear_cache!
@@cache = {}.with_indifferent_access
end
#-------------------------------------------------------------------
def method_missing(method, *args)
super
rescue NoMethodError
method_name = method.to_s
if method_name.last == "="
self[method_name.sub("=", "")] = args.first
else
self[method_name]
end
end
# Get setting value (from database or loaded YAML files)
#-------------------------------------------------------------------
def [](name)
# Return value if cached
return cache[name] if cache.key?(name)
# Check database
if database_and_table_exists?
if setting = find_by_name(name.to_s)
return cache[name] = setting.value unless setting.value.nil?
end
end
# Check YAML settings
return cache[name] = yaml_settings[name] if yaml_settings.key?(name)
end
# Set setting value
#-------------------------------------------------------------------
def []=(name, value)
return nil unless database_and_table_exists?
setting = find_by_name(name.to_s) || new(name: name)
setting.value = value
setting.save
cache[name] = value
end
# Unrolls [ :one, :two ] settings array into [[ "One", :one ], [ "Two", :two ]]
# picking symbol translations from locale. If setting is not a symbol but
# string it gets copied without translation.
#-------------------------------------------------------------------
def unroll(setting)
send(setting).map { |key| [key.is_a?(Symbol) ? I18n.t(key) : key, key.to_sym] }
end
def database_and_table_exists?
# Returns false if table or database is unavailable.
# Catches all database-related errors, so that Setting will return nil
# instead of crashing the entire application.
table_exists? rescue false
end
# Loads settings from YAML files
def load_settings_from_yaml(file)
settings = YAML.load(ERB.new(File.read(file)).result)
@@yaml_settings.deep_merge!(settings)
end
end
ActiveSupport.run_load_hooks(:fat_free_crm_setting, self)
end