diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb index ff994a483..c9efa2ca3 100644 --- a/lib/site_setting_extension.rb +++ b/lib/site_setting_extension.rb @@ -46,6 +46,10 @@ module SiteSettingExtension @choices ||= {} end + def shadowed_settings + @shadowed_settings ||= [] + end + def hidden_settings @hidden_settings ||= [] end @@ -84,6 +88,15 @@ module SiteSettingExtension hidden_settings << name end + # You can "shadow" a site setting with a GlobalSetting. If the GlobalSetting + # exists it will be used instead of the setting and the setting will be hidden. + # Useful for things like API keys on multisite. + if opts[:shadowed_by_global] && GlobalSetting.respond_to?(name) + hidden_settings << name + shadowed_settings << name + current_value = GlobalSetting.send(name) + end + if opts[:refresh] refresh_settings << name end @@ -97,7 +110,7 @@ module SiteSettingExtension end current[name] = current_value - setup_methods(name, current_value) + setup_methods(name) end end @@ -133,7 +146,7 @@ module SiteSettingExtension # Retrieve all settings def all_settings(include_hidden=false) @defaults - .reject{|s, _| hidden_settings.include?(s) || include_hidden} + .reject{|s, _| hidden_settings.include?(s) && !include_hidden} .map do |s, v| value = send(s) type = types[get_data_type(s, value)] @@ -177,9 +190,11 @@ module SiteSettingExtension if deletions.length > 0 || changes.length > 0 changes.each do |name, val| + next if shadowed_settings.include?(name) current[name] = val end deletions.each do |name,val| + next if shadowed_settings.include?(name) current[name] = defaults[name] end end @@ -364,7 +379,7 @@ module SiteSettingExtension end - def setup_methods(name, current_value) + def setup_methods(name) clean_name = name.to_s.sub("?", "") eval "define_singleton_method :#{clean_name} do diff --git a/spec/components/site_setting_extension_spec.rb b/spec/components/site_setting_extension_spec.rb index 1e0adca5a..b9c8cf253 100644 --- a/spec/components/site_setting_extension_spec.rb +++ b/spec/components/site_setting_extension_spec.rb @@ -339,4 +339,71 @@ describe SiteSettingExtension do end end + describe "hidden" do + before do + settings.setting(:superman_identity, 'Clark Kent', hidden: true) + settings.refresh! + end + + it "is in the `hidden_settings` collection" do + settings.hidden_settings.include?(:superman_identity).should == true + end + + it "can be retrieved" do + settings.superman_identity.should == "Clark Kent" + end + + it "is not present in all_settings by default" do + settings.all_settings.find {|s| s[:setting] == :superman_identity }.should be_blank + end + + it "is present in all_settings when we ask for hidden" do + settings.all_settings(true).find {|s| s[:setting] == :superman_identity }.should be_present + end + end + + describe "shadowed_by_global" do + context "without global setting" do + before do + settings.setting(:trout_api_key, 'evil', shadowed_by_global: true) + settings.refresh! + end + + it "should not add the key to the shadowed_settings collection" do + settings.shadowed_settings.include?(:trout_api_key).should == false + end + + it "can return the default value" do + settings.trout_api_key.should == 'evil' + end + + it "can overwrite the default" do + settings.trout_api_key = 'tophat' + settings.refresh! + settings.trout_api_key.should == 'tophat' + end + end + + context "with global setting" do + before do + GlobalSetting.stubs(:trout_api_key).returns('purringcat') + settings.setting(:trout_api_key, 'evil', shadowed_by_global: true) + settings.refresh! + end + + it "should return the global setting instead of default" do + settings.trout_api_key.should == 'purringcat' + end + + it "should return the global setting after a refresh" do + settings.refresh! + settings.trout_api_key.should == 'purringcat' + end + + it "should add the key to the shadowed_settings collection" do + settings.shadowed_settings.include?(:trout_api_key).should == true + end + end + end + end