thecore_settings 1.1.15 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +20 -0
- data/.devcontainer/devcontainer.json +33 -0
- data/.github/workflows/gempush.yml +34 -0
- data/.gitignore +542 -0
- data/.rakeTasks +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +31 -0
- data/CHANGELOG.md +81 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +275 -0
- data/LICENSE.txt +22 -0
- data/README.md +169 -0
- data/README.rdoc +68 -0
- data/Rakefile +6 -34
- data/app/{assets/config/thecore_settings_manifest.js → models/.keep} +0 -0
- data/app/models/thecore_settings/setting.rb +77 -0
- data/app/views/.keep +0 -0
- data/app/views/rails_admin/main/_setting_value.html.haml +41 -0
- data/bin/rails +13 -0
- data/config/locales/en.yml +29 -0
- data/config/locales/{thecore_settings.it.yml → it.yml} +2 -2
- data/config/locales/pt-BR.yml +28 -0
- data/config/locales/ru.yml +29 -0
- data/db/migrate/20161227101954_create_rails_admin_settings.rb +4 -4
- data/gemfiles/mongoid-6.0.gemfile +5 -0
- data/gemfiles/mongoid-6.3.gemfile +5 -0
- data/lib/generators/thecore_settings/migration_generator.rb +15 -0
- data/lib/generators/thecore_settings/templates/db/migrate/20161227101954_create_thecore_settings.rb +29 -0
- data/lib/generators/thecore_settings/templates/migration.rb +29 -0
- data/lib/thecore_settings/determine_mime_type.rb +193 -0
- data/lib/thecore_settings/dumper.rb +12 -0
- data/lib/thecore_settings/engine.rb +17 -3
- data/lib/thecore_settings/fallback.rb +21 -0
- data/lib/thecore_settings/hex_color_validator.rb +11 -0
- data/lib/thecore_settings/kinds.rb +34 -0
- data/lib/thecore_settings/mongoid.rb +19 -0
- data/lib/thecore_settings/namespaced.rb +210 -0
- data/lib/thecore_settings/processing.rb +217 -0
- data/lib/thecore_settings/rails_admin_config.rb +71 -0
- data/lib/thecore_settings/require_helpers.rb +86 -0
- data/lib/thecore_settings/settings.rb +95 -0
- data/lib/thecore_settings/storage/carrier_wave_uploader.rb +9 -0
- data/lib/thecore_settings/storage/shrine_uploader.rb +14 -0
- data/lib/thecore_settings/tasks.rb +35 -0
- data/lib/thecore_settings/uploads.rb +57 -0
- data/lib/thecore_settings/validation.rb +126 -0
- data/lib/thecore_settings/version.rb +1 -1
- data/lib/thecore_settings.rb +115 -123
- data/spec/advanced_usage_spec.rb +11 -0
- data/spec/carrierwave_spec.rb +41 -0
- data/spec/database_trickery_spec.rb +48 -0
- data/spec/defaults_spec.rb +87 -0
- data/spec/enabling_spec.rb +29 -0
- data/spec/factories/setting.rb +8 -0
- data/spec/label_spec.rb +16 -0
- data/spec/migration_spec.rb +20 -0
- data/spec/model_spec.rb +105 -0
- data/spec/namespaced_spec.rb +67 -0
- data/spec/paperclip_spec.rb +38 -0
- data/spec/settings_spec.rb +75 -0
- data/spec/shrine_spec.rb +34 -0
- data/spec/spec_helper.rb +85 -0
- data/spec/support/1024x768.gif +0 -0
- data/spec/support/database_cleaner.rb +10 -0
- data/spec/support/defaults.yml +23 -0
- data/spec/support/defaults_w_file.yml +19 -0
- data/spec/support/mongoid.rb +6 -0
- data/spec/support/mongoid.yml +6 -0
- data/spec/types_spec.rb +101 -0
- data/thecore_settings.gemspec +44 -0
- metadata +326 -63
- data/app/assets/stylesheets/rich/editor.css +0 -20
- data/config/initializers/rails_admin_requirements.rb +0 -22
- data/config/initializers/thecore_settings_abilities.rb +0 -22
- data/config/initializers/thecore_settings_post_init.rb +0 -9
- data/config/routes.rb +0 -3
- data/db/migrate/20161227101956_add_app_name.rb +0 -5
- data/lib/tasks/thecore_settings_tasks.rake +0 -4
@@ -0,0 +1,193 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Shrine
|
4
|
+
module Plugins
|
5
|
+
# Documentation can be found on https://shrinerb.com/docs/plugins/determine_mime_type
|
6
|
+
module DetermineMimeType
|
7
|
+
LOG_SUBSCRIBER = -> (event) do
|
8
|
+
Shrine.logger.info "MIME Type (#{event.duration}ms) – #{{
|
9
|
+
io: event[:io].class,
|
10
|
+
uploader: event[:uploader],
|
11
|
+
}.inspect}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.configure(uploader, log_subscriber: LOG_SUBSCRIBER, **opts)
|
15
|
+
uploader.opts[:determine_mime_type] ||= { analyzer: :file, analyzer_options: {} }
|
16
|
+
uploader.opts[:determine_mime_type].merge!(opts)
|
17
|
+
|
18
|
+
# instrumentation plugin integration
|
19
|
+
uploader.subscribe(:mime_type, &log_subscriber) if uploader.respond_to?(:subscribe)
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
# Determines the MIME type of the IO object by calling the specified
|
24
|
+
# analyzer.
|
25
|
+
def determine_mime_type(io)
|
26
|
+
analyzer = opts[:determine_mime_type][:analyzer]
|
27
|
+
|
28
|
+
analyzer = mime_type_analyzer(analyzer) if analyzer.is_a?(Symbol)
|
29
|
+
args = if analyzer.is_a?(Proc)
|
30
|
+
[io, mime_type_analyzers].take(analyzer.arity.abs)
|
31
|
+
else
|
32
|
+
[io, opts[:determine_mime_type][:analyzer_options]]
|
33
|
+
end
|
34
|
+
|
35
|
+
mime_type = instrument_mime_type(io) { analyzer.call(*args) }
|
36
|
+
io.rewind
|
37
|
+
|
38
|
+
mime_type
|
39
|
+
end
|
40
|
+
alias mime_type determine_mime_type
|
41
|
+
|
42
|
+
# Returns a hash of built-in MIME type analyzers, where keys are
|
43
|
+
# analyzer names and values are `#call`-able objects which accepts the
|
44
|
+
# IO object.
|
45
|
+
def mime_type_analyzers
|
46
|
+
@mime_type_analyzers ||= MimeTypeAnalyzer::SUPPORTED_TOOLS.inject({}) do |hash, tool|
|
47
|
+
hash.merge!(tool => mime_type_analyzer(tool))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns callable mime type analyzer object.
|
52
|
+
def mime_type_analyzer(name)
|
53
|
+
MimeTypeAnalyzer.new(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Sends a `mime_type.shrine` event for instrumentation plugin.
|
59
|
+
def instrument_mime_type(io, &block)
|
60
|
+
return yield unless respond_to?(:instrument)
|
61
|
+
|
62
|
+
instrument(:mime_type, io: io, &block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module InstanceMethods
|
67
|
+
private
|
68
|
+
|
69
|
+
# Calls the configured MIME type analyzer.
|
70
|
+
def extract_mime_type(io)
|
71
|
+
self.class.determine_mime_type(io)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class MimeTypeAnalyzer
|
76
|
+
SUPPORTED_TOOLS = [:fastimage, :file, :filemagic, :mimemagic, :marcel, :mime_types, :mini_mime, :content_type]
|
77
|
+
MAGIC_NUMBER = 256 * 1024
|
78
|
+
|
79
|
+
def initialize(tool)
|
80
|
+
raise Error, "unknown mime type analyzer #{tool.inspect}, supported analyzers are: #{SUPPORTED_TOOLS.join(",")}" unless SUPPORTED_TOOLS.include?(tool)
|
81
|
+
|
82
|
+
@tool = tool
|
83
|
+
end
|
84
|
+
|
85
|
+
def call(io, options = {})
|
86
|
+
mime_type = send(:"extract_with_#{@tool}", io, options)
|
87
|
+
io.rewind
|
88
|
+
|
89
|
+
mime_type
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def extract_with_file(io, options)
|
95
|
+
require "open3"
|
96
|
+
|
97
|
+
return nil if io.eof? # file command returns "application/x-empty" for empty files
|
98
|
+
|
99
|
+
Open3.popen3(*%W[file --mime-type --brief -]) do |stdin, stdout, stderr, thread|
|
100
|
+
begin
|
101
|
+
IO.copy_stream(io, stdin.binmode)
|
102
|
+
rescue Errno::EPIPE
|
103
|
+
end
|
104
|
+
stdin.close
|
105
|
+
|
106
|
+
status = thread.value
|
107
|
+
|
108
|
+
raise Error, "file command failed to spawn: #{stderr.read}" if status.nil?
|
109
|
+
raise Error, "file command failed: #{stderr.read}" unless status.success?
|
110
|
+
|
111
|
+
$stderr.print(stderr.read)
|
112
|
+
|
113
|
+
output = stdout.read.strip
|
114
|
+
|
115
|
+
raise Error, "file command failed: #{output}" if output.include?("cannot open")
|
116
|
+
|
117
|
+
output
|
118
|
+
end
|
119
|
+
rescue Errno::ENOENT
|
120
|
+
raise Error, "file command-line tool is not installed"
|
121
|
+
end
|
122
|
+
|
123
|
+
def extract_with_fastimage(io, options)
|
124
|
+
require "fastimage"
|
125
|
+
|
126
|
+
type = FastImage.type(io)
|
127
|
+
"image/#{type}" if type
|
128
|
+
end
|
129
|
+
|
130
|
+
def extract_with_filemagic(io, options)
|
131
|
+
require "filemagic"
|
132
|
+
|
133
|
+
return nil if io.eof? # FileMagic returns "application/x-empty" for empty files
|
134
|
+
|
135
|
+
FileMagic.open(FileMagic::MAGIC_MIME_TYPE) do |filemagic|
|
136
|
+
filemagic.buffer(io.read(MAGIC_NUMBER))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def extract_with_mimemagic(io, options)
|
141
|
+
require "mimemagic"
|
142
|
+
|
143
|
+
mime = MimeMagic.by_magic(io)
|
144
|
+
mime&.type
|
145
|
+
end
|
146
|
+
|
147
|
+
def extract_with_marcel(io, options)
|
148
|
+
require "marcel"
|
149
|
+
|
150
|
+
return nil if io.eof? # marcel returns "application/octet-stream" for empty files
|
151
|
+
|
152
|
+
filename = (options[:filename_fallback] ? extract_filename(io) : nil)
|
153
|
+
Marcel::MimeType.for(io, name: filename)
|
154
|
+
end
|
155
|
+
|
156
|
+
def extract_with_mime_types(io, options)
|
157
|
+
require "mime/types"
|
158
|
+
|
159
|
+
if filename = extract_filename(io)
|
160
|
+
mime_type = MIME::Types.of(filename).first
|
161
|
+
mime_type&.content_type
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def extract_with_mini_mime(io, options)
|
166
|
+
require "mini_mime"
|
167
|
+
|
168
|
+
if filename = extract_filename(io)
|
169
|
+
info = MiniMime.lookup_by_filename(filename)
|
170
|
+
info&.content_type
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def extract_with_content_type(io, options)
|
175
|
+
if io.respond_to?(:content_type) && io.content_type
|
176
|
+
io.content_type.split(";").first
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def extract_filename(io)
|
181
|
+
if io.respond_to?(:original_filename)
|
182
|
+
io.original_filename
|
183
|
+
elsif io.respond_to?(:path)
|
184
|
+
File.basename(io.path)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
register_plugin(:determine_mime_type, DetermineMimeType)
|
192
|
+
end
|
193
|
+
end
|
@@ -1,10 +1,24 @@
|
|
1
1
|
module ThecoreSettings
|
2
2
|
class Engine < ::Rails::Engine
|
3
|
-
|
3
|
+
rake_tasks do
|
4
|
+
require File.expand_path('../tasks', __FILE__)
|
5
|
+
end
|
6
|
+
|
7
|
+
initializer 'ThecoreSettings.install_after_action' do |app|
|
8
|
+
require File.dirname(__FILE__) + '/../../app/models/thecore_settings/setting.rb'
|
9
|
+
|
10
|
+
if defined?(ActionController) and defined?(ActionController::Base)
|
11
|
+
ActionController::Base.class_eval do
|
12
|
+
after_action { Settings.unload! }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
initializer 'ThecoreSettings.add_to_migrations' do |app|
|
4
18
|
unless app.root.to_s.match root.to_s
|
5
19
|
# APPEND TO MAIN APP MIGRATIONS FROM THIS GEM
|
6
|
-
config.paths[
|
7
|
-
app.config.paths[
|
20
|
+
config.paths['db/migrate'].expanded.each do |expanded_path|
|
21
|
+
app.config.paths['db/migrate'] << expanded_path
|
8
22
|
end
|
9
23
|
end
|
10
24
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ThecoreSettings
|
2
|
+
# we are inheriting from BasicObject so we don't get a bunch of methods from
|
3
|
+
# Kernel or Object
|
4
|
+
class Fallback < BasicObject
|
5
|
+
def initialize(ns, fb)
|
6
|
+
@ns = ns
|
7
|
+
@fb = fb
|
8
|
+
end
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#<ThecoreSettings::Fallback ns: #{@ns.inspect}, fb: #{@fb.inspect}>"
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(*args)
|
15
|
+
@ns.ns_mutex.synchronize do
|
16
|
+
@ns.fallback = @fb
|
17
|
+
@ns.__send__(*args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module ThecoreSettings
|
2
|
+
class HexColorValidator < ActiveModel::EachValidator
|
3
|
+
def validate_each(record, attribute, value)
|
4
|
+
record.errors[attribute] << (options[:message] || I18n.t('admin.settings.color_invalid')) unless value.blank? || self.class.matches?(value)
|
5
|
+
end
|
6
|
+
def self.matches?(value)
|
7
|
+
return false unless value
|
8
|
+
/^(?:[0-9a-f]{3})(?:[0-9a-f]{3})?$/i.match(value).nil? ? false : true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ThecoreSettings
|
2
|
+
def self.kinds
|
3
|
+
[
|
4
|
+
'string',
|
5
|
+
'text',
|
6
|
+
'integer',
|
7
|
+
'float',
|
8
|
+
'boolean',
|
9
|
+
'html',
|
10
|
+
'code',
|
11
|
+
'sanitized',
|
12
|
+
'yaml',
|
13
|
+
'phone',
|
14
|
+
'phones',
|
15
|
+
'email',
|
16
|
+
'address',
|
17
|
+
'file',
|
18
|
+
'image',
|
19
|
+
'url',
|
20
|
+
'domain',
|
21
|
+
'color',
|
22
|
+
'strip_tags',
|
23
|
+
'sanitize',
|
24
|
+
'sanitize_code',
|
25
|
+
'simple_format',
|
26
|
+
'simple_format_raw',
|
27
|
+
'json',
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.types
|
32
|
+
self.kinds
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ThecoreSettings
|
2
|
+
module Mongoid
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
include ::Mongoid::Document
|
6
|
+
include ::Mongoid::Timestamps::Short
|
7
|
+
|
8
|
+
store_in collection: "thecore_settings"
|
9
|
+
field :enabled, type: ::Mongoid::VERSION.to_i < 4 ? Boolean : ::Mongoid::Boolean, default: true
|
10
|
+
field :kind, type: String, default: ThecoreSettings.types.first
|
11
|
+
field :ns, type: String, default: 'main'
|
12
|
+
field :key, type: String
|
13
|
+
field :raw, type: String
|
14
|
+
field :label, type: String
|
15
|
+
index({ns: 1, key: 1}, {unique: true, sparse: true})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,210 @@
|
|
1
|
+
module ThecoreSettings
|
2
|
+
# we are inheriting from BasicObject so we don't get a bunch of methods from
|
3
|
+
# Kernel or Object
|
4
|
+
class Namespaced < BasicObject
|
5
|
+
attr_accessor :settings, :fallback
|
6
|
+
attr_reader :loaded, :mutex, :ns_mutex, :name
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
self.settings = {}
|
10
|
+
@mutex = ::Mutex.new
|
11
|
+
@ns_mutex = ::Mutex.new
|
12
|
+
@loaded = false
|
13
|
+
@locked = false
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
def nil?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
def inspect
|
21
|
+
"#<ThecoreSettings::Namespaced name: #{@name.inspect}, fallback: #{@fallback.inspect}, loaded: #{@loaded}>"
|
22
|
+
end
|
23
|
+
def pretty_inspect
|
24
|
+
inspect
|
25
|
+
end
|
26
|
+
|
27
|
+
def load!
|
28
|
+
mutex.synchronize do
|
29
|
+
return if loaded
|
30
|
+
@loaded = true
|
31
|
+
@settings = {}
|
32
|
+
::ThecoreSettings::Setting.ns(@name).each do |setting|
|
33
|
+
@settings[setting.key] = setting
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def unload!
|
39
|
+
mutex.synchronize do
|
40
|
+
@loaded = false
|
41
|
+
@settings = {}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# returns setting object
|
46
|
+
def get(key, options = {})
|
47
|
+
load!
|
48
|
+
key = key.to_s
|
49
|
+
mutex.synchronize do
|
50
|
+
@locked = true
|
51
|
+
v = @settings[key]
|
52
|
+
if v.nil?
|
53
|
+
unless @fallback.nil? || @fallback == @name
|
54
|
+
v = ::Settings.ns(@fallback).getnc(key)
|
55
|
+
end
|
56
|
+
if v.nil?
|
57
|
+
v = set(key, options[:default], options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@locked = false
|
61
|
+
v
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# returns setting object
|
66
|
+
def getnc(key)
|
67
|
+
load!
|
68
|
+
mutex.synchronize do
|
69
|
+
self.settings[key]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def set(key, value = nil, options = {})
|
74
|
+
load! unless @locked
|
75
|
+
key = key.to_s
|
76
|
+
options.symbolize_keys!
|
77
|
+
|
78
|
+
if !options[:type].nil? && options[:type] == 'yaml' && !value.nil?
|
79
|
+
if value.class.name != 'String'
|
80
|
+
value = value.to_yaml
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
options.merge!(value: value)
|
85
|
+
if @locked
|
86
|
+
write_to_database(key, options)
|
87
|
+
else
|
88
|
+
mutex.synchronize do
|
89
|
+
write_to_database(key, options)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def enabled?(key, options = {})
|
95
|
+
get(key, options).enabled?
|
96
|
+
end
|
97
|
+
|
98
|
+
def []=(key, value)
|
99
|
+
set(key, value)
|
100
|
+
end
|
101
|
+
def [](key)
|
102
|
+
get(key)
|
103
|
+
end
|
104
|
+
|
105
|
+
def destroy!(key)
|
106
|
+
load!
|
107
|
+
key = key.to_s
|
108
|
+
mutex.synchronize do
|
109
|
+
::ThecoreSettings::Setting.where(ns: @name, key: key).destroy_all
|
110
|
+
@settings.delete(key)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def destroy_all!
|
115
|
+
mutex.synchronize do
|
116
|
+
::ThecoreSettings::Setting.where(ns: @name).destroy_all
|
117
|
+
@loaded = false
|
118
|
+
@settings = {}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# returns processed setting value
|
123
|
+
def method_missing(key, *args)
|
124
|
+
key = key.to_s
|
125
|
+
if key.end_with?('_enabled?')
|
126
|
+
key = key[0..-10]
|
127
|
+
v = get(key)
|
128
|
+
if v.nil?
|
129
|
+
set(key, '').enabled
|
130
|
+
else
|
131
|
+
v.enabled
|
132
|
+
end
|
133
|
+
elsif key.end_with?('_enabled=')
|
134
|
+
key = key[0..-10]
|
135
|
+
v = get(key)
|
136
|
+
if ::ThecoreSettings.mongoid?
|
137
|
+
if ::Mongoid::VERSION >= "4.0.0"
|
138
|
+
v.set(enabled: args.first)
|
139
|
+
else
|
140
|
+
v.set("enabled", args.first)
|
141
|
+
end
|
142
|
+
else
|
143
|
+
v.enabled = args.first
|
144
|
+
v.save!
|
145
|
+
end
|
146
|
+
v.enabled
|
147
|
+
elsif key.end_with?('=')
|
148
|
+
key = key[0..-2]
|
149
|
+
options = args[1] || {}
|
150
|
+
value = args.first
|
151
|
+
set(key, value, options).val
|
152
|
+
else
|
153
|
+
v = get(key, args.first || {})
|
154
|
+
if v.nil?
|
155
|
+
''
|
156
|
+
else
|
157
|
+
v.val
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def write_to_database(key, options)
|
163
|
+
is_file = !options[:kind].nil? && (options[:kind] == 'image' || options[:kind] == 'file')
|
164
|
+
if is_file
|
165
|
+
options[:raw] = ''
|
166
|
+
file = options[:value]
|
167
|
+
else
|
168
|
+
options[:raw] = options[:value]
|
169
|
+
end
|
170
|
+
|
171
|
+
options.delete(:value)
|
172
|
+
options.delete(:default)
|
173
|
+
options[:ns] = @name
|
174
|
+
|
175
|
+
if @settings[key].nil?
|
176
|
+
options.delete(:overwrite)
|
177
|
+
v = ::ThecoreSettings::Setting.create(options.merge(key: key))
|
178
|
+
if !v.persisted?
|
179
|
+
if v.errors[:key].any?
|
180
|
+
v = ::ThecoreSettings::Setting.where(key: key).first
|
181
|
+
if v.nil?
|
182
|
+
::Kernel.raise ::ThecoreSettings::PersistenceException, 'Fatal: error in key and not in DB'
|
183
|
+
end
|
184
|
+
else
|
185
|
+
::Kernel.raise ::ThecoreSettings::PersistenceException, v.errors.full_messages.join(',')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
@settings[key] = v
|
189
|
+
else
|
190
|
+
opts = options.dup
|
191
|
+
if options[:overwrite] == false && !@settings[key].value.blank?
|
192
|
+
opts.delete(:raw)
|
193
|
+
opts.delete(:value)
|
194
|
+
opts.delete(:enabled)
|
195
|
+
end
|
196
|
+
opts.delete(:overwrite)
|
197
|
+
# Pre Rails 6.1 vs Post Rails 6.1
|
198
|
+
# In Rails 6.1 update_attributes has been deprecated
|
199
|
+
@settings[key].respond_to?('update_attributes!') ? @settings[key].update_attributes!(opts) : @settings[key].update!(opts)
|
200
|
+
end
|
201
|
+
if is_file
|
202
|
+
if options[:overwrite] != false || !@settings[key].file?
|
203
|
+
@settings[key].file = file
|
204
|
+
@settings[key].save!
|
205
|
+
end
|
206
|
+
end
|
207
|
+
@settings[key]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|